public inbox for [email protected]  
help / color / mirror / Atom feed
[pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
10+ messages / 3 participants
[nested] [flat]

* [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
@ 2022-03-14 13:47 Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Pradip Parkale @ 2022-03-14 13:47 UTC (permalink / raw)
  To: pgadmin-hackers

Hi Hackers,

Please find the attached patch for #7132
<https://redmine.postgresql.org/issues/7132; Port Properties collection,
Dashboard and SQL panel in React.


-- 
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation


Attachments:

  [application/x-patch] RM7132.patch (437.7K, 3-RM7132.patch)
  download | inline diff:
diff --git a/web/package.json b/web/package.json
index e4a27bd10..3c8e769ea 100644
--- a/web/package.json
+++ b/web/package.json
@@ -87,6 +87,8 @@
     "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "4.0.0-alpha.58",
     "@material-ui/pickers": "^3.2.10",
+    "@mui/icons-material": "^5.4.2",
+    "@mui/material": "^5.4.3",
     "@projectstorm/react-diagrams": "^6.6.1",
     "@simonwep/pickr": "^1.5.1",
     "@szhsin/react-menu": "^2.2.0",
@@ -122,6 +124,7 @@
     "date-fns": "^2.24.0",
     "diff-arrays-of-objects": "^1.1.8",
     "dropzone": "^5.9.3",
+    "html-loader": "^3.1.0",
     "html2canvas": "^1.0.0-rc.7",
     "immutability-helper": "^3.0.0",
     "imports-loader": "^2.0.0",
@@ -154,6 +157,7 @@
     "react-checkbox-tree": "^1.7.2",
     "react-dom": "^17.0.1",
     "react-draggable": "^4.4.4",
+    "react-router-dom": "^6.2.2",
     "react-select": "^4.2.1",
     "react-table": "^7.6.3",
     "react-timer-hook": "^3.0.5",
diff --git a/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js b/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
index dd9874976..d1ee8b3b3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
@@ -68,25 +68,6 @@ define('pgadmin.node.cast', [
 
       },
 
-      // Define the backform model for cast node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Define the schema for cast
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          editable: false, type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode: ['properties'],
-        },
-        {
-          id: 'description', label: gettext('Comment'),
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        },
-        ],
-      }),
-
       getSchema: function(treeNodeInfo, itemNodeData){
         return new CastSchema({
           getTypeOptions: ()=>getNodeAjaxOptions('get_type', this, treeNodeInfo, itemNodeData),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
index c6d7a7e51..5e830af87 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
@@ -12,9 +12,8 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../static/
 
 define('pgadmin.node.event_trigger', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for event trigger collection
   if (!pgBrowser.Nodes['coll-event_trigger']) {
@@ -80,132 +79,6 @@ define('pgadmin.node.event_trigger', [
           }
         );
       },
-      // Define the model for event trigger node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          oid: undefined,
-          name: undefined,
-          eventowner: undefined,
-          is_sys_obj: undefined,
-          comment: undefined,
-          enabled: 'O',
-          eventfuncoid: undefined,
-          eventfunname: undefined,
-          eventname: 'DDL_COMMAND_START',
-          when: undefined,
-          xmin: undefined,
-          source: undefined,
-          language: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'eventowner': userInfo.name}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the event trigger node
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'eventowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'edit','create'], node: 'role',
-          control: Backform.NodeListByNameControl,
-        },{
-          id: 'is_sys_obj', label: gettext('System event trigger?'),
-          cell:'boolean', type: 'switch',
-          mode: ['properties'],
-        },{
-          id: 'comment', label: gettext('Comment'), type: 'multiline',
-        },{
-          id: 'enabled', label: gettext('Trigger enabled?'),
-          group: gettext('Definition'), mode: ['properties', 'edit','create'],
-          options: [
-            {label: gettext('Enable'), value: 'O'},
-            {label: gettext('Disable'), value: 'D'},
-            {label: gettext('Replica'), value: 'R'},
-            {label: gettext('Always'), value: 'A'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'eventfunname', label: gettext('Trigger function'),
-          type: 'text', control: 'node-ajax-options', group: gettext('Definition'),
-          url:'fopts', cache_node: 'trigger_function',
-        },{
-          id: 'eventname', label: gettext('Event'),
-          group: gettext('Definition'), cell: 'string',
-          options: [
-            {label: gettext('DDL COMMAND START'), value: 'DDL_COMMAND_START'},
-            {label: gettext('DDL COMMAND END'), value: 'DDL_COMMAND_END'},
-            {label: gettext('SQL DROP'), value: 'SQL_DROP'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'when', label: gettext('When TAG in'),  cell: 'string',
-          type: 'text', group: gettext('Definition'),
-          control: Backform.SqlFieldControl,
-          extraClasses:['custom_height_css_class'],
-        },{
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
-          group: gettext('Security'), mode: ['edit', 'create'],
-          min_version: 90200, canAdd: true,
-          canEdit: false, canDelete: true, control: 'unique-col-collection',
-        },
-        ],
-        // event trigger model data validation.
-        validate: function() {
-          var msg = undefined;
-          // Clear any existing error msg.
-          this.errorModel.clear();
-
-          if (_.isUndefined(this.get('name'))
-              || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventowner'))
-              || String(this.get('eventowner')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger owner cannot be empty.');
-            this.errorModel.set('eventowner', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('enabled'))) {
-            msg = gettext('Event trigger enabled status cannot be empty.');
-            this.errorModel.set('enabled', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventfunname'))
-              || String(this.get('eventfunname')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger function cannot be empty.');
-            this.errorModel.set('eventfunname', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventname'))) {
-            msg = gettext('Event trigger event cannot be empty.');
-            this.errorModel.set('eventname', msg);
-            return msg;
-          }
-
-          return null;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
index 6045b0c75..82001e107 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
@@ -13,9 +13,8 @@ import ExtensionsSchema from './extension.ui';
 
 define('pgadmin.node.extension', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   /*
    * Create and Add an Extension Collection into nodes
@@ -96,109 +95,6 @@ define('pgadmin.node.extension', [
        * Define model for the Node and specify the properties
        * of the model in schema.
        */
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [
-          {
-            id: 'name', label: gettext('Name'), first_empty: true,
-            type: 'text', mode: ['properties', 'create', 'edit'],
-            visible: true, url:'avails', readonly: function(m) {
-              return !m.isNew();
-            },
-            transform: function(data, cell) {
-              var res = [],
-                control = cell || this,
-                label = control.model.get('name');
-
-              if (!control.model.isNew()) {
-                res.push({label: label, value: label});
-              }
-              else {
-                if (data && _.isArray(data)) {
-                  _.each(data, function(d) {
-                    if (d.installed_version === null)
-
-                      /*
-                       * d contains json data and sets into
-                       * select's option control
-                       *
-                       * We need to stringify data because formatter will
-                       * convert Array Object as [Object] string
-                       */
-                      res.push({label: d.name, value: JSON.stringify(d)});
-                  });
-                }
-              }
-              return res;
-            },
-
-            /*
-             * extends NodeAjaxOptionsControl to override the properties
-             * getValueFromDOM which takes stringified data from option of
-             * select control and parse it. And `onChange` takes the stringified
-             * data from select's option, thus convert it to json format and set the
-             * data into Model which is used to enable/disable the schema field.
-             */
-            control: Backform.NodeAjaxOptionsControl.extend({
-              getValueFromDOM: function() {
-                var data = this.formatter.toRaw(
-                  _.unescape(this.$el.find('select').val()), this.model);
-                /*
-                 * return null if data is empty to prevent it from
-                 * throwing parsing error. Adds check as name can be empty
-                 */
-                if (data === '') {
-                  return null;
-                }
-                else if (typeof(data) === 'string') {
-                  data=JSON.parse(data);
-                }
-                return data.name;
-              },
-
-              /*
-               * When name is changed, extract value from its select option and
-               * set attributes values into the model
-               */
-              onChange: function() {
-                Backform.NodeAjaxOptionsControl.prototype.onChange.apply(
-                  this, arguments
-                );
-                var selectedValue = this.$el.find('select').val();
-                if (selectedValue.trim() != '') {
-                  var d = this.formatter.toRaw(selectedValue, this.model);
-                  if(typeof(d) === 'string')
-                    d=JSON.parse(d);
-                  this.model.set({
-                    'version' : '',
-                    'relocatable': (
-                      (!_.isNull(d.relocatable[0]) &&
-                        !_.isUndefined(d.relocatable[0])) ? d.relocatable[0]: ''
-                    ),
-                  });
-                } else {
-                  this.model.set({
-                    'version': '', 'relocatable': true, 'schema': '',
-                  });
-                }
-              },
-            }),
-          },
-          {
-            id: 'oid', label: gettext('OID'), cell: 'string',
-            type: 'text', mode: ['properties'],
-          },
-          {
-            id: 'owner', label: gettext('Owner'), control: 'node-list-by-name',
-            mode: ['properties'], node: 'role', cell: 'string',
-            cache_level: 'server',
-          },
-          {
-            id: 'comment', label: gettext('Comment'), cell: 'string',
-            type: 'multiline', readonly: true,
-          },
-        ],
-      }),
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['extension'];
         return new ExtensionsSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
index 8f0ed95ef..4dc85aae0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
@@ -13,9 +13,9 @@ import ForeignServerSchema from './foreign_server.ui';
 
 define('pgadmin.node.foreign_server', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/pgadmin',
-  'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
+  'pgadmin.browser', 'pgadmin.browser.collection',
   'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for foreign server collection
   if (!pgBrowser.Nodes['coll-foreign_server']) {
@@ -82,45 +82,6 @@ define('pgadmin.node.foreign_server', [
           }
         );
       },
-
-      // Defining model for foreign server node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'fsrvowner': userInfo.name}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Defining schema for the foreign server node
-        schema: [
-          {
-            id: 'name', label: gettext('Name'), cell: 'string',
-            type: 'text', disabled: function() {
-              return (
-                this.mode == 'edit' && this.node_info.server.version < 90200
-              );
-            },
-          }, {
-            id: 'oid', label: gettext('OID'), cell: 'string',
-            type: 'text', mode: ['properties'],
-          }, {
-            id: 'fsrvowner', label: gettext('Owner'), type: 'text',
-            control: Backform.NodeListByNameControl, node: 'role',
-            mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
-          }, {
-            id: 'description', label: gettext('Comment'), cell: 'string',
-            type: 'multiline',
-          },
-        ],
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
index 5c5be3c85..b45be8187 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
@@ -12,10 +12,10 @@ import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
 import ForeignDataWrapperSchema from './foreign_data_wrapper.ui';
 
 define('pgadmin.node.foreign_data_wrapper', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/gettext', 'sources/url_for', 'jquery',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for foreign data wrapper collection
   if (!pgBrowser.Nodes['coll-foreign_data_wrapper']) {
@@ -87,44 +87,6 @@ define('pgadmin.node.foreign_data_wrapper', [
           }
         );
       },
-
-      // Defining model for foreign data wrapper node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'fdwowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Defining schema for the foreign data wrapper node
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: function() {
-            // name field will be disabled only if edit mode
-            return (
-              this.mode == 'edit'
-            );
-          },
-        }, {
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        }, {
-          id: 'fdwowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
index aaabe734d..56dc670a1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
@@ -10,13 +10,12 @@
 import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../static/js/node_ajax';
 import LanguageSchema from './language.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
-import _ from 'lodash';
 
 define('pgadmin.node.language', [
   'sources/gettext', 'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for languages collection
   if (!pgBrowser.Nodes['coll-language']) {
@@ -71,37 +70,6 @@ define('pgadmin.node.language', [
         }]);
       },
 
-      // Define the model for language node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'lanowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the language node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },{
-          id: 'lanowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false },
-        },
-        {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        },
-        ],
-      }),
 
       getSchema: function(treeNodeInfo, itemNodeData){
         return new LanguageSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
index b767057cd..697ddf265 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
@@ -12,9 +12,9 @@ import PublicationSchema from './publication.ui';
 
 define('pgadmin.node.publication', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for publications collection
   if (!pgBrowser.Nodes['coll-publication']) {
@@ -23,7 +23,7 @@ define('pgadmin.node.publication', [
         node: 'publication',
         label: gettext('Publications'),
         type: 'coll-publication',
-        columns: ['name', 'pubowner', 'pubtable', 'all_table'],
+        columns: ['name', 'pubowner', 'proptable', 'all_table'],
 
       });
   }
@@ -70,82 +70,7 @@ define('pgadmin.node.publication', [
           icon: 'wcTabIcon icon-publication', data: {action: 'create'},
         }]);
       },
-      // Define the model for publication node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
 
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'pubowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the publication node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-          visible: function() {
-            if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
-              && !_.isUndefined(this.node_info.server.version) &&
-                this.node_info.server.version >= 100000) {
-              return true;
-            }
-            return false;
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },{
-          id: 'pubowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          disabled: function(m){
-            if(m.isNew())
-              return true;
-            return false;
-          },
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
-        },{
-          id: 'all_table', label: gettext('All tables?'), type: 'switch',
-          group: gettext('Definition'), mode: ['edit', 'properties', 'create'], deps: ['name'],
-          readonly: function(m) {return !m.isNew();},
-        },
-        {
-          id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
-          mode: ['properties'],
-        },
-        ],
-
-
-        /* validate function is used to validate the input given by
-         * the user. In case of error, message will be displayed on
-         * the GUI for the respective control.
-         */
-
-        sessChanged: function() {
-          if (this.sessAttrs['pubtable'] == '' && this.origSessAttrs['pubtable'] == '')
-            return false;
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-
-        canCreate: function(itemData, item) {
-
-          var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
-            server = treeData['server'];
-
-          // If server is less than 10 then do not allow 'create' menu
-          if (server && server.version < 100000)
-            return false;
-
-          // by default we want to allow create menu
-          return true;
-        },
-
-      }),
 
       getSchema: function(treeNodeInfo, itemNodeData){
         return new PublicationSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
index 46cfb0e87..55736d4b0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
@@ -147,7 +147,7 @@ export default class PublicationSchema extends BaseUISchema {
       group: gettext('Definition'), mode: ['edit', 'create'],
       deps: ['all_table'], disabled: obj.isAllTable,
     },{
-      id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
+      id: 'proptable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
       mode: ['properties'],
     },{
       type: 'nested-fieldset', mode: ['create','edit', 'properties'],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
index 58eac45a8..668b4eba5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
@@ -1,3 +1,6 @@
 SELECT pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
-AS pubtable  FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
+AS pubtable,
+pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
+AS proptable
+  FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
 AND pgb_table.schemaname NOT LIKE 'pgagent';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
index 25c0f04fc..df8d9b4f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
@@ -45,37 +45,6 @@ define('pgadmin.node.aggregate', [
 
         this.initialized = true;
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Aggregate'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }
-        ],
-      }),
       getSchema: ()=>{
         return new AggregateSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
index 8785d147a..e1152eb22 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
@@ -45,32 +45,6 @@ define('pgadmin.node.catalog_object_column', [
         getSchema: function() {
           return new CatalogObjectColumnSchema();
         },
-        model: pgAdmin.Browser.Node.Model.extend({
-          defaults: {
-            attname: undefined,
-            attowner: undefined,
-            atttypid: undefined,
-            attnum: undefined,
-            cltype: undefined,
-            collspcname: undefined,
-            attacl: undefined,
-            is_sys_obj: undefined,
-            description: undefined,
-          },
-          schema: [{
-            id: 'attname', label: gettext('Column'), cell: 'string',
-            type: 'text', readonly: true,
-          },{
-            id: 'attnum', label: gettext('Position'), cell: 'string',
-            type: 'text', readonly: true,
-          },{
-            id: 'cltype', label: gettext('Data type'), cell: 'string',
-            group: gettext('Definition'), type: 'text', readonly: true,
-          },{
-            id: 'description', label: gettext('Comment'), cell: 'string',
-            type: 'multiline', readonly: true,
-          }],
-        }),
       });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
index 06753a427..dac46721a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
@@ -43,31 +43,6 @@ define('pgadmin.node.catalog_object', [
 
       },
       getSchema: ()=>new CatalogObjectSchema(),
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgAdmin.Browser.Node.Model.extend({
-        defaults: {
-          name: undefined,
-          namespaceowner: undefined,
-          nspacl: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline' ,  readonly: true,
-        },
-        ],
-      }),
 
     });
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
index 586f410bc..4d3dff132 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
@@ -69,42 +69,6 @@ define('pgadmin.node.collation', [
         ]);
 
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema', control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }
-        ],
-      }),
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['collation'];
         return new CollationSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
index 67f23e5ca..4c6594ddb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
@@ -75,43 +75,6 @@ define('pgadmin.node.domain_constraints', [
       getSchema: function() {
         return new DomainConstraintSchema();
       },
-
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        // Domain Constraint Schema
-        schema: [{
-          id: 'name', label: gettext('Name'), type:'text', cell:'string',
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline', cell:
-          'string', mode: ['properties', 'create', 'edit'], min_version: 90500,
-        }],
-        // Client Side Validation
-        validate: function() {
-          var err = {},
-            errmsg;
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('consrc')) || String(this.get('consrc')).replace(/^\s+|\s+$/g, '') == '') {
-            err['consrc'] = gettext('Check cannot be empty.');
-            errmsg = errmsg || err['consrc'];
-
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
index a14fbf395..8b2b361f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
@@ -98,38 +98,6 @@ define('pgadmin.node.domain', [
           }
         );
       },
-
-      // Domain Node Model
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema = args.node_info.schema.label;
-            this.set({'basensp': schema}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'owner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        // Domain Schema
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string', control: Backform.NodeListByNameControl,
-          node: 'role',  type: 'text', mode: ['edit', 'create', 'properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
index 8e6059486..3affdeefb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
@@ -10,15 +10,16 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../stat
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import ForeignTableSchema from './foreign_table.ui';
+import _ from 'lodash';
 
 /* Create and Register Foreign Table Collection and Node. */
 define('pgadmin.node.foreign_table', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.backgrid',
+  'sources/gettext', 'sources/url_for', 'jquery', 'backbone',
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backgrid',
   'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node',
   'pgadmin.browser.collection',
 ], function(
-  gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser, Backform, Backgrid,
+  gettext, url_for, $, Backbone, pgAdmin, pgBrowser, Backgrid,
   schemaChild, schemaChildTreeNode
 ) {
 
@@ -34,465 +35,6 @@ define('pgadmin.node.foreign_table', [
       });
   }
 
-  // Options Model
-  var ColumnOptionsModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'option',
-    defaults: {
-      option: undefined,
-      value: undefined,
-    },
-    schema: [
-      {id: 'option', label: gettext('Option'), type:'text', editable: true, cellHeaderClasses: 'width_percent_30'},
-      {
-        id: 'value', label: gettext('Value'), type: 'text', editable: true, cellHeaderClasses: 'width_percent_50',
-      },
-    ],
-    validate: function() {
-      if (_.isUndefined(this.get('value')) ||
-          _.isNull(this.get('value')) ||
-          String(this.get('value')).replace(/^\s+|\s+$/g, '') == '') {
-        var msg = 'Please enter a value.';
-
-        this.errorModel.set('value', msg);
-
-        return msg;
-      } else {
-        this.errorModel.unset('value');
-      }
-
-      return null;
-    },
-  });
-
-  // Columns Model
-  var ColumnsModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'attnum',
-    defaults: {
-      attname: undefined,
-      datatype: undefined,
-      typlen: undefined,
-      precision: undefined,
-      typdefault: undefined,
-      attnotnull: undefined,
-      collname: undefined,
-      attnum: undefined,
-      inheritedfrom: undefined,
-      inheritedid: undefined,
-      attstattarget: undefined,
-      coloptions: [],
-    },
-    type_options: undefined,
-    schema: [{
-      id: 'attname', label: gettext('Name'), cell: 'string', type: 'text',
-      editable: 'is_editable_column', cellHeaderClasses: 'width_percent_40',
-    },{
-      id: 'datatype', label: gettext('Data type'), cell: 'node-ajax-options',
-      control: 'node-ajax-options', type: 'text', url: 'get_types',
-      editable: 'is_editable_column', cellHeaderClasses: 'width_percent_0',
-      group: gettext('Definition'),
-      transform: function(d, self){
-        self.model.type_options = d;
-        return d;
-      },
-    },
-    {
-      id: 'typlen', label: gettext('Length'),
-      cell: 'string', group: gettext('Definition'),
-      type: 'int', deps: ['datatype'],
-      disabled: function(m) {
-        var val = m.get('typlen');
-        // We will store type from selected from combobox
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) {
-
-          if (!_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('typlen', undefined);
-            }, 10);
-          }
-          return true;
-        }
-
-        var of_type = m.get('datatype'),
-          has_length = false;
-        if(m.type_options) {
-          m.set('is_tlength', false, {silent: true});
-
-          // iterating over all the types
-          _.each(m.type_options, function(o) {
-            // if type from selected from combobox matches in options
-            if ( of_type == o.value ) {
-              // if length is allowed for selected type
-              if(o.length)
-              {
-                // set the values in model
-                has_length = true;
-                m.set('is_tlength', true, {silent: true});
-                m.set('min_val', o.min_val, {silent: true});
-                m.set('max_val', o.max_val, {silent: true});
-              }
-            }
-          });
-
-          if (!has_length && !_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('typlen', undefined);
-            }, 10);
-          }
-
-          return !(m.get('is_tlength'));
-        }
-        if (!has_length && !_.isUndefined(val)) {
-          setTimeout(function() {
-            m.set('typlen', undefined);
-          }, 10);
-        }
-        return true;
-      },
-      cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'precision', label: gettext('Precision'),
-      type: 'int', deps: ['datatype'],
-      cell: 'string', group: gettext('Definition'),
-      disabled: function(m) {
-        var val = m.get('precision');
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) {
-
-          if (!_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('precision', undefined);
-            }, 10);
-          }
-          return true;
-        }
-
-        var of_type = m.get('datatype'),
-          has_precision = false;
-
-        if(m.type_options) {
-          m.set('is_precision', false, {silent: true});
-          // iterating over all the types
-          _.each(m.type_options, function(o) {
-            // if type from selected from combobox matches in options
-            if ( of_type == o.value ) {
-              // if precession is allowed for selected type
-              if(o.precision)
-              {
-                has_precision = true;
-                // set the values in model
-                m.set('is_precision', true, {silent: true});
-                m.set('min_val', o.min_val, {silent: true});
-                m.set('max_val', o.max_val, {silent: true});
-              }
-            }
-          });
-          if (!has_precision && !_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('precision', undefined);
-            }, 10);
-          }
-          return !(m.get('is_precision'));
-        }
-        if (!has_precision && !_.isUndefined(val)) {
-          setTimeout(function() {
-            m.set('precision', undefined);
-          }, 10);
-        }
-        return true;
-      }, cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'typdefault', label: gettext('Default'), type: 'text',
-      cell: 'string', min_version: 90300, group: gettext('Definition'),
-      placeholder: gettext('Enter an expression or a value.'),
-      cellHeaderClasses: 'width_percent_10',
-      editable: function(m) {
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) { return false; }
-        if (this.get('node_info').server.version < 90300){
-          return false;
-        }
-        return true;
-      },
-    },
-    {
-      id: 'attnotnull', label: gettext('Not NULL?'),
-      cell: 'boolean',type: 'switch', editable: 'is_editable_column',
-      cellHeaderClasses: 'width_percent_10', group: gettext('Definition'),
-    },
-    {
-      id: 'attstattarget', label: gettext('Statistics'), min_version: 90200,
-      cell: 'integer', type: 'int', group: gettext('Definition'),
-      editable: function(m) {
-        if (_.isUndefined(m.isNew) || m.isNew()) { return false; }
-        if (this.get('node_info').server.version < 90200){
-          return false;
-        }
-        return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-          || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-      }, cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'collname', label: gettext('Collation'), cell: 'node-ajax-options',
-      control: 'node-ajax-options', type: 'text', url: 'get_collations',
-      min_version: 90300, editable: function(m) {
-        if (!(_.isUndefined(m.isNew)) && !m.isNew()) { return false; }
-        return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-           || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-      },
-      cellHeaderClasses: 'width_percent_20', group: gettext('Definition'),
-    },
-    {
-      id: 'attnum', cell: 'string',type: 'text', visible: false,
-    },
-    {
-      id: 'inheritedfrom', label: gettext('Inherited From'), cell: 'string',
-      type: 'text', visible: false, mode: ['properties', 'edit'],
-      cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'coloptions', label: gettext('Options'), cell: 'string',
-      type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
-      model: ColumnOptionsModel, canAdd: true, canDelete: true, canEdit: false,
-      control: Backform.UniqueColCollectionControl, uniqueCol : ['option'],
-      min_version: 90200,
-    }],
-    validate: function() {
-      var errmsg = null;
-
-      if (_.isUndefined(this.get('attname')) || String(this.get('attname')).replace(/^\s+|\s+$/g, '') == '') {
-        errmsg = gettext('Column Name cannot be empty.');
-        this.errorModel.set('attname', errmsg);
-      } else {
-        this.errorModel.unset('attname');
-      }
-
-      if (_.isUndefined(this.get('datatype')) || String(this.get('datatype'))
-        .replace(/^\s+|\s+$/g, '') == '') {
-        errmsg = gettext('Column Datatype cannot be empty.');
-        this.errorModel.set('datatype', errmsg);
-      } else {
-        this.errorModel.unset('datatype');
-      }
-
-      return errmsg;
-    },
-    is_editable_column: function(m) {
-      return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-       || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
-  /* NodeAjaxOptionsMultipleControl is for multiple selection of Combobox.
-  *  This control is used to select Multiple Parent Tables to be inherited.
-  *  It also populates/vacates Columns on selection/deselection of the option (i.e. table name).
-  *  To populates the column, it calls the server and fetch the columns data
-  *  for the selected table.
-  */
-  var NodeAjaxOptionsMultipleControl = Backform.NodeAjaxOptionsControl.extend({
-    onChange: function() {
-      var model = this.model,
-        attrArr = this.field.get('name').split('.'),
-        name = attrArr.shift(),
-        path = attrArr.join('.'),
-        value = this.getValueFromDOM(),
-        changes = {},
-        columns = model.get('columns'),
-        inherits = model.get(name);
-
-      if (this.model.errorModel instanceof Backbone.Model) {
-        if (_.isEmpty(path)) {
-          this.model.errorModel.unset(name);
-        } else {
-          var nestedError = this.model.errorModel.get(name);
-          if (nestedError) {
-            this.keyPathSetter(nestedError, path, null);
-            this.model.errorModel.set(name, nestedError);
-          }
-        }
-      }
-
-      var self = this;
-
-      if (typeof(inherits)  == 'string'){ inherits = JSON.parse(inherits); }
-
-      // Remove Columns if inherit option is deselected from the combobox
-      if(_.size(value) < _.size(inherits)) {
-        var dif =  _.difference(inherits, value);
-        var rmv_columns = columns.where({inheritedid: parseInt(dif[0])});
-        columns.remove(rmv_columns);
-      }
-      else
-      {
-        _.each(value, function(i) {
-          // Fetch Columns from server
-          var fnd_columns = columns.where({inheritedid: parseInt(i)});
-          if (fnd_columns && fnd_columns.length <= 0) {
-            var inhted_columns = self.fetchColumns(i);
-            columns.add(inhted_columns);
-          }
-        });
-      }
-
-      changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
-      this.stopListening(this.model, 'change:' + name, this.render);
-      model.set(changes);
-      this.listenTo(this.model, 'change:' + name, this.render);
-    },
-    fetchColumns: function(table_id){
-      var self = this,
-        url = 'get_columns',
-        m = self.model.top || self.model;
-
-      var node = this.field.get('schema_node'),
-        node_info = this.field.get('node_info'),
-        full_url = node.generate_url.apply(
-          node, [
-            null, url, this.field.get('node_data'),
-            this.field.get('url_with_id') || false, node_info,
-          ]),
-        cache_level = this.field.get('cache_level') || node.type,
-        cache_node = this.field.get('cache_node');
-
-      cache_node = (cache_node && pgBrowser.Nodes['cache_node']) || node;
-
-      m.trigger('pgadmin:view:fetching', m, self.field);
-      var data = {attrelid: table_id};
-
-      // Fetching Columns data for the selected table.
-      $.ajax({
-        async: false,
-        url: full_url,
-        data: data,
-      })
-        .done(function(res) {
-        /*
-         * We will cache this data for short period of time for avoiding
-         * same calls.
-         */
-          data = cache_node.cache(url, node_info, cache_level, res.data);
-
-        })
-        .fail(function() {
-          m.trigger('pgadmin:view:fetch:error', m, self.field);
-        });
-      m.trigger('pgadmin:view:fetched', m, self.field);
-
-      // To fetch only options from cache, we do not need time from 'at'
-      // attribute but only options.
-      //
-      // It is feasible that the data may not have been fetched.
-      data = (data && data.data) || [];
-      return data;
-
-    },
-  });
-
-
-  // Constraints Model
-  var ConstraintModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'conoid',
-    initialize: function(attrs) {
-      var isNew = (_.size(attrs) === 0);
-      if (!isNew) {
-        this.convalidated_default = this.get('convalidated');
-      }
-      pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-    },
-    defaults: {
-      conoid: undefined,
-      conname: undefined,
-      consrc: undefined,
-      connoinherit: undefined,
-      convalidated: true,
-      conislocal: undefined,
-    },
-    convalidated_default: true,
-    schema: [{
-      id: 'conoid', type: 'text', cell: 'string', visible: false,
-    },{
-      id: 'conname', label: gettext('Name'), type: 'text', cell: 'string',
-      editable: 'is_editable', cellHeaderClasses: 'width_percent_30',
-    },{
-      id: 'consrc', label: gettext('Check'), type: 'multiline',
-      editable: 'is_editable', cell: Backgrid.Extension.TextareaCell,
-      cellHeaderClasses: 'width_percent_30',
-    },{
-      id: 'connoinherit', label: gettext('No inherit?'), type: 'switch',
-      cell: 'boolean', editable: 'is_editable',
-      cellHeaderClasses: 'width_percent_20',
-    },{
-      id: 'convalidated', label: gettext('Validate?'), type: 'switch',
-      cell: 'boolean', cellHeaderClasses: 'width_percent_20',
-      editable: function(m) {
-        if (_.isUndefined(m.isNew)) { return true; }
-        if (!m.isNew()) {
-          if(m.get('convalidated') && m.convalidated_default) {
-            return false;
-          }
-          return true;
-        }
-        return true;
-      },
-    },
-    ],
-    validate: function() {
-      var err = {},
-        errmsg;
-
-      if (_.isUndefined(this.get('conname')) || String(this.get('conname')).replace(/^\s+|\s+$/g, '') == '') {
-        err['conname'] = gettext('Constraint Name cannot be empty.');
-        errmsg = err['conname'];
-      }
-
-      if (_.isUndefined(this.get('consrc')) || String(this.get('consrc'))
-        .replace(/^\s+|\s+$/g, '') == '') {
-        err['consrc'] = gettext('Constraint Check cannot be empty.');
-        errmsg = errmsg || err['consrc'];
-      }
-
-      this.errorModel.clear().set(err);
-
-      return errmsg;
-    },
-    is_editable: function(m) {
-      return _.isUndefined(m.isNew) ? true : m.isNew();
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
-  // Options Model
-  var OptionsModel = pgBrowser.Node.Model.extend({
-    defaults: {
-      option: undefined,
-      value: undefined,
-    },
-    schema: [{
-      id: 'option', label: gettext('Option'), cell: 'string', type: 'text',
-      editable: true, cellHeaderClasses:'width_percent_50',
-    },{
-      id: 'value', label: gettext('Value'), cell: 'string',type: 'text',
-      editable: true, cellHeaderClasses:'width_percent_50',
-    },
-    ],
-    validate: function() {
-      // TODO: Add validation here
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
   if (!pgBrowser.Nodes['foreign_table']) {
     pgBrowser.Nodes['foreign_table'] = schemaChild.SchemaChildNode.extend({
       type: 'foreign_table',
@@ -561,160 +103,6 @@ define('pgadmin.node.foreign_table', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var schema = args.node_info.schema._label,
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            // Set Selected Schema and Current User
-            this.set({
-              'basensp': schema, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          owner: undefined,
-          basensp: undefined,
-          is_sys_obj: undefined,
-          description: undefined,
-          ftsrvname: undefined,
-          strftoptions: undefined,
-          inherits: [],
-          columns: [],
-          constraints: [],
-          ftoptions: [],
-          relacl: [],
-          stracl: [],
-          seclabels: [],
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl,
-          node: 'role',  type: 'text', select2: { allowClear: false },
-        },{
-          id: 'basensp', label: gettext('Schema'), cell: 'node-list-by-name',
-          control: 'node-list-by-name', cache_level: 'database', type: 'text',
-          node: 'schema', mode:['create', 'edit'],
-        },{
-          id: 'is_sys_obj', label: gettext('System foreign table?'),
-          cell:'boolean', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        },{
-          id: 'ftsrvname', label: gettext('Foreign server'), cell: 'string', control: 'node-ajax-options',
-          type: 'text', group: gettext('Definition'), url: 'get_foreign_servers',
-          readonly: function(m) { return !m.isNew(); }, cache_node: 'database',
-        },{
-          id: 'inherits', label: gettext('Inherits'), group: gettext('Definition'),
-          type: 'array', min_version: 90500, control: NodeAjaxOptionsMultipleControl,
-          url: 'get_tables', select2: {multiple: true},
-          'cache_level': 'database',
-          transform: function(d) {
-            if (this.field.get('mode') == 'edit') {
-              var oid = this.model.get('oid');
-              var s = _.findWhere(d, {'id': oid});
-              if (s) {
-                d = _.reject(d, s);
-              }
-            }
-            return d;
-          },
-        },{
-          id: 'columns', label: gettext('Columns'), cell: 'string',
-          type: 'collection', group: gettext('Columns'), mode: ['edit', 'create'],
-          model: ColumnsModel, canAdd: true, canDelete: true, canEdit: true,
-          columns: ['attname', 'datatype', 'inheritedfrom'],
-          canDeleteRow: function(m) {
-            return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-              || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-          },
-          canEditRow: function(m) {
-            return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-              || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-          },
-        },
-        {
-          id: 'constraints', label: gettext('Constraints'), cell: 'string',
-          type: 'collection', group: gettext('Constraints'), mode: ['edit', 'create'],
-          model: ConstraintModel, canAdd: true, canDelete: true, columns: ['conname','consrc', 'connoinherit', 'convalidated'],
-          canEdit: function(o) {
-            if (o instanceof Backbone.Model) {
-              if (o instanceof ConstraintModel) {
-                return o.isNew();
-              }
-            }
-            return true;
-          }, min_version: 90500, canDeleteRow: function(m) {
-            return (m.get('conislocal') == true || _.isUndefined(m.get('conislocal'))) ? true : false;
-          },
-        },{
-          id: 'strftoptions', label: gettext('Options'), cell: 'string',
-          type: 'text', group: gettext('Definition'), mode: ['properties'],
-        },{
-          id: 'ftoptions', label: gettext('Options'), cell: 'string',
-          type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
-          model: OptionsModel, canAdd: true, canDelete: true, canEdit: false,
-          control: 'unique-col-collection', uniqueCol : ['option'],
-        },{
-          id: 'relacl', label: gettext('Privileges'), cell: 'string',
-          type: 'text', group: gettext('Security'),
-          mode: ['properties'], min_version: 90200,
-        }, pgBrowser.SecurityGroupSchema, {
-          id: 'acl', label: gettext('Privileges'), model: pgAdmin
-            .Browser.Node.PrivilegeRoleModel.extend(
-              {privileges: ['a','r','w','x']}), uniqueCol : ['grantee', 'grantor'],
-          editable: false, type: 'collection', group: 'security',
-          mode: ['edit', 'create'],
-          canAdd: true, canDelete: true, control: 'unique-col-collection',
-          min_version: 90200,
-        },{
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, type: 'collection',
-          group: 'security', mode: ['edit', 'create'],
-          min_version: 90100, canAdd: true,
-          canEdit: false, canDelete: true,
-          control: 'unique-col-collection', uniqueCol : ['provider'],
-        },
-        ],
-        validate: function()
-        {
-          var err = {},
-            errmsg = null;
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('basensp')) || String(this.get('basensp'))
-            .replace(/^\s+|\s+$/g, '') == '') {
-            err['basensp'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['basensp'];
-          }
-
-          if (_.isUndefined(this.get('ftsrvname')) || String(this.get('ftsrvname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['ftsrvname'] = gettext('Foreign server cannot be empty.');
-            errmsg = errmsg || err['ftsrvname'];
-          }
-
-          this.errorModel.clear().set(err);
-
-          return errmsg;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
index 0049de5bd..073dd4acc 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
@@ -93,32 +93,6 @@ define('pgadmin.node.fts_configuration', [
           }
         );
       },
-
-      // Defining model for FTS Configuration node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        initialize: function(attrs, opts) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-          if (isNew) {
-            var user = pgBrowser.serverInfo[opts.node_info.server._id].user;
-            this.set({
-              'owner': user.name,
-              'schema': opts.node_info.schema._id,
-            }, {silent: true});
-          }
-        },
-        // Defining schema for FTS Configuration
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
index 5d5bd3a8f..0ea741034 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
@@ -88,31 +88,6 @@ define('pgadmin.node.fts_dictionary', [
           }
         );
       },
-
-      // Defining backform model for FTS Dictionary node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-          if (isNew) {
-            var user = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'owner': user.name,
-              'schema': args.node_info.schema._id,
-            }, {silent: true});
-          }
-        },
-        // Defining schema for fts dictionary
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
index 27a4ce87f..ad5579d0d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
@@ -70,108 +70,6 @@ define('pgadmin.node.fts_parser', [
 
       },
 
-      // Defining backform model for fts parser node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,          // Fts parser name
-          is_sys_obj: undefined,  // Is system object
-          description: undefined,   // Comment on parser
-        },
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(
-            this, arguments
-          );
-          if (isNew) {
-            this.set('schema', args.node_info.schema._id);
-          }
-        },
-        // Defining schema for fts parser
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode:['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-
-        /*
-         * Triggers control specific error messages for parser name,
-         * start, token, end, lextype functions and schema, if any one of them is not specified
-         * while creating new fts parser
-         */
-        validate: function() {
-          var name = this.get('name'),
-            start = this.get('prsstart'),
-            token = this.get('prstoken'),
-            end = this.get('prsend'),
-            lextype = this.get('prslextype'),
-            schema = this.get('schema'),
-            msg;
-
-          // Validate fts parser name
-          if (_.isUndefined(name) ||
-                _.isNull(name) ||
-                String(name).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name must be specified.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          // Validate start function control
-          else if (_.isUndefined(start) ||
-                    _.isNull(start) ||
-                    String(start).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Start function must be selected.');
-            this.errorModel.set('prsstart', msg);
-            return msg;
-          }
-
-          // Validate gettoken function control
-          else if (_.isUndefined(token) ||
-                    _.isNull(token) ||
-                    String(token).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Get next token function must be selected.');
-            this.errorModel.set('prstoken', msg);
-            return msg;
-          }
-
-          // Validate end function control
-          else if (_.isUndefined(end) ||
-                    _.isNull(end) ||
-                    String(end).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('End function must be selected.');
-            this.errorModel.set('prsend', msg);
-            return msg;
-          }
-
-          // Validate lextype function control
-          else if (_.isUndefined(lextype) ||
-                    _.isNull(lextype) ||
-                    String(lextype).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Lextype function must be selected.');
-            this.errorModel.set('prslextype', msg);
-            return msg;
-          }
-
-          // Validate schema for fts parser
-          else if (_.isUndefined(schema) ||
-                    _.isNull(schema) ||
-                    String(schema).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Schema must be selected.');
-            this.errorModel.set('schema', msg);
-            return msg;
-          }
-          else this.errorModel.clear();
-
-          this.trigger('on-status-clear');
-          return null;
-        },
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['fts_parser'];
         return new FTSParserSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
index 791adb2f9..5320246f3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
@@ -70,65 +70,6 @@ define('pgadmin.node.fts_template', [
 
       },
 
-      // Defining backform model for fts template node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-          if (isNew) {
-            this.set('schema', args.node_info.schema._id);
-          }
-        },
-        // Defining schema for fts template
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode:['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-
-        /*
-         * Triggers control specific error messages for template name,
-         * lexize function and schema, if any one of them is not specified
-         * while creating new fts template
-         */
-        validate: function() {
-          var name = this.get('name'),
-            lexize = this.get('tmpllexize'),
-            schema = this.get('schema'),
-            msg;
-
-          // Validate fts template name
-          if (_.isUndefined(name) || _.isNull(name) || String(name).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name must be specified.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          // Validate lexize function control
-          else if (_.isUndefined(lexize) || _.isNull(lexize) || String(lexize).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Lexize function must be selected.');
-            this.errorModel.set('tmpllexize', msg);
-            return msg;
-          }
-
-          // Validate schema for fts template
-          else if (_.isUndefined(schema) || _.isNull(schema) || String(schema).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Schema must be selected.');
-            this.errorModel.set('schema', msg);
-            return msg;
-          }
-          else this.errorModel.clear();
-
-          this.trigger('on-status-clear');
-          return null;
-        },
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['fts_template'];
         return new FTSTemplateSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
index 41171c62a..b9107d98f 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
 import FunctionSchema from './function.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
-import _ from 'lodash';
 
 /* Create and Register Function Collection and Node. */
 define('pgadmin.node.function', [
@@ -109,44 +108,7 @@ define('pgadmin.node.function', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema_id = args.node_info.schema._id;
-            this.set({'pronamespace': schema_id}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'funcowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'isDisabled',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'funcowner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl, node: 'role',  type:
-          'text', disabled: 'isDisabled',
-        },{
-          id: 'pronamespace', label: gettext('Schema'), cell: 'string',
-          control: 'node-list-by-id', type: 'text', cache_level: 'database',
-          node: 'schema', disabled: 'isDisabled', mode: ['create', 'edit'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled',
-        }],
-      }),
     });
-
   }
-
   return pgBrowser.Nodes['function'];
 });
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
index 1b6b61863..7cbcdc907 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
 import FunctionSchema from './function.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
-import _ from 'lodash';
 
 /* Create and Register Procedure Collection and Node. */
 define('pgadmin.node.procedure', [
@@ -126,126 +125,6 @@ define('pgadmin.node.procedure', [
         );
       },
 
-      model: Function.model.extend({
-        defaults: _.extend({},
-          Function.model.prototype.defaults,
-          {
-            lanname: 'edbspl',
-          }
-        ),
-        canVarAdd: function() {
-          var server = this.node_info.server;
-          return server.version >= 90500;
-        },
-        isVisible: function() {
-          if (this.name == 'sysfunc') { return false; }
-          else if (this.name == 'sysproc') { return true; }
-          return false;
-        },
-        isDisabled: function(m) {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          switch(this.name){
-          case 'provolatile':
-          case 'proisstrict':
-          case 'procost':
-          case 'proleakproof':
-            if(this.node_info.server.version < 90500 ||
-              this.node_info.server.server_type != 'ppas' ||
-              m.get('lanname') != 'edbspl') {
-
-              setTimeout(function() {
-                m.set('provolatile', null);
-                m.set('proisstrict', false);
-                m.set('procost', null);
-                m.set('proleakproof', false);
-              }, 10);
-              return true;
-            }
-            else{
-              return false;
-            }
-          case 'variables':
-          case 'prosecdef':
-            return this.node_info.server.version < 90500;
-          case 'prorows':
-            var server = this.node_info.server;
-            return !(server.version >= 90500 && m.get('proretset') == true);
-          case 'proparallel':
-            if (this.node_info.server.version < 90600 ||
-              this.node_info.server.server_type != 'ppas' ||
-              m.get('lanname') != 'edbspl') {
-              setTimeout(function() {
-                m.set('proparallel', null);
-              }, 10);
-              return true;
-            }
-            else{
-              return false;
-            }
-          case 'lanname':
-            return this.node_info.server.version < 110000;
-          default:
-            return false;
-          }
-        },
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          return null;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
index ec0b9f2c5..1eed8e8bf 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
@@ -107,151 +107,6 @@ define('pgadmin.node.trigger_function', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema_id = args.node_info.schema._id;
-            this.set({'pronamespace': schema_id}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'funcowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          funcowner: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'isDisabled', readonly: 'isReadonly',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'funcowner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl, node: 'role',  type:
-          'text', disabled: 'isDisabled', readonly: 'isReadonly',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled', readonly: 'isReadonly',
-        }],
-        validate: function(keys)
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          // Nothing to validate
-          if(keys && keys.length == 0) {
-            this.errorModel.clear();
-            return null;
-          }
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') {
-            err['funcowner'] = gettext('Owner cannot be empty.');
-            errmsg = errmsg || err['funcowner'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') {
-            err['prorettypename'] = gettext('Return type cannot be empty.');
-            errmsg = errmsg || err['prorettypename'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-        isVisible: function() {
-          if (this.name == 'sysproc') { return false; }
-          return true;
-        },
-        isReadonly: function(m) {
-          switch(this.name){
-          case 'proargs':
-          case 'proargtypenames':
-          case 'prorettypename':
-          case 'proretset':
-          case 'proiswindow':
-            return !m.isNew();
-          default:
-            return false;
-          }
-        },
-        isDisabled: function(m) {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          if (this.name === 'prorows'){
-            if(m.get('proretset') == true) {
-              return false;
-            }
-            return true;
-          } else {
-            return false;
-          }
-        },
-        canVarAdd: function() {
-          return !(this.node_info &&  'catalog' in this.node_info);
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
index 98fff6bab..3a2bb65a8 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
@@ -45,37 +45,6 @@ define('pgadmin.node.operator', [
 
         this.initialized = true;
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Operator'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }
-        ],
-      }),
       getSchema: ()=>{
         return new OperatorSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
index a3c340407..d9ebb9d3d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
@@ -48,16 +48,6 @@ define('pgadmin.node.edbvar', [
       },
       canDrop: false,
       canDropCascade: false,
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        }]
-      }),
       getSchema: () => {
         return new EDBVarSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
index a2ce63fc3..003f379bd 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
@@ -92,41 +92,6 @@ define('pgadmin.node.package', [
         // by default we want to allow create menu
         return true;
       },
-      // Define the model for package node.
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({
-              'owner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        // Define the schema for package node.
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: function(m) {
-            return !m.isNew();
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: true, editable: false, visible: function(m) {
-            return !m.isNew();
-          },
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }]
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         var nodeObj = pgBrowser.Nodes['package'];
         return new PackageSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
index 6c358fd58..0e336682a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
@@ -106,41 +106,6 @@ define('pgadmin.node.sequence', [
           }
         );
       },
-
-      // Define the model for sequence node.
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'seqowner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for sequence node.
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'seqowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
-          control: Backform.NodeListByNameControl,
-        },{
-          id: 'comment', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
index c41cbd5d2..42d182c48 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
@@ -42,25 +42,6 @@ define('pgadmin.node.catalog', [
         this.initialized = true;
 
       },
-      model: pgBrowser.Node.Model.extend({
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'namespaceowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        }]
-      }),
       getSchema: function(treeNodeInfo) {
         return new CatalogSchema(
           {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
index ee384f629..4822c204d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
@@ -361,36 +361,6 @@ define('pgadmin.node.schema', [
       can_create_schema: function(node) {
         return pgBrowser.Nodes['database'].is_conn_allow.call(this, node);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'namespaceowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'namespaceowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', control: 'node-list-by-name', node: 'role',
-          select2: { allowClear: false },
-        },{
-          id: 'is_sys_obj', label: gettext('System schema?'),
-          cell: 'switch', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline'
-        }]
-      }),
       getSchema: function(treeNodeInfo, itemNodeData) {
         var schemaObj = pgBrowser.Nodes['schema'];
         return new PGSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
index 8181fdc94..104324cb3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
@@ -100,54 +100,6 @@ define('pgadmin.node.synonym', [
           }
         );
       },
-
-      model: pgAdmin.Browser.Node.Model.extend({
-        isNew: function() {
-          return !this.fetchFromServer;
-        },
-        idAttribute: 'oid',
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-            this.set({
-              'owner': userInfo.name,
-              'synobjschema': schemaInfo._label,
-              'schema': schemaInfo._label,
-              'targettype': 'r',
-            }, {silent: true});
-          } else {
-            this.fetchFromServer = true;
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema', readonly: function(m) { return !m.isNew(); },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: true , control: 'node-list-by-name',
-          node: 'role', visible: false,
-        }],
-
-        // We will disable everything if we are under catalog node
-        inSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-      }),
       canCreate: function(itemData, item, data) {
         //If check is false then , we will allow create menu
         if (data && data.check == false)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
index 5e12f159a..4df6c7ae7 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
@@ -98,36 +98,6 @@ define('pgadmin.node.column', [
       getSchema: function(treeNodeInfo, itemNodeData) {
         return getNodeColumnSchema(treeNodeInfo, itemNodeData, pgBrowser);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'attnum',
-
-        defaults: {
-          name: undefined,
-          attnum: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchemaWithColumnCheck',
-          cellHeaderClasses:'width_percent_30',
-          editable: 'editable_check_for_table',
-        },{
-          id: 'attnum', label: gettext('Position'), cell: 'string',
-          type: 'text', disabled: 'notInSchema', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'notInSchema',
-        }],
-        // We will check if we are under schema node & in 'create' mode
-        notInSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-      }),
       // Below function will enable right click menu for creating column
       canCreate: function(itemData, item, data) {
         // If check is false then , we will allow create menu
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
index 433828373..06b41026a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
@@ -189,16 +189,6 @@ define('pgadmin.node.compound_trigger', [
         );
       },
 
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }],
-      }),
       canCreate: function(itemData, item, data) {
         //If check is false then , we will allow create menu
         if (data && data.check == false)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
index d135deae5..df5f0e4cb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
@@ -43,24 +43,6 @@ define('pgadmin.node.constraints', [
 
         pgBrowser.add_menus([]);
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          comment: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('Oid'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
index 3fb8a6c17..cb1749c08 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
@@ -92,29 +92,6 @@ define('pgadmin.node.index', [
       },
       canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          nspname: undefined,
-          tabname: undefined,
-          spcname: undefined,
-          amname: 'btree',
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'int', readonly: true, mode: ['properties'],
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }],
-      }),
       // Below function will enable right click menu for creating column
       canCreate: function(itemData, item, data) {
         // If check is false then , we will allow create menu
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
index 6836ce30c..d0a1eec5f 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
@@ -305,49 +305,6 @@ function(
       getSchema: function(treeNodeInfo, itemNodeData) {
         return getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowser);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          description: undefined,
-          is_partitioned: false,
-          partition_value: undefined,
-        },
-        // Default values!
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[
-                args.node_info.server._id
-              ].user,
-              schemaInfo = args.node_info.schema;
-
-            this.set({
-              'relowner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), type: 'text', mode: ['properties'],
-        },{
-          id: 'schema', label: gettext('Schema'), type: 'text', node: 'schema',
-          mode: ['create', 'edit', 'properties'],
-        },{
-          id: 'is_partitioned', label:gettext('Partitioned table?'), cell: 'switch',
-          type: 'switch', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'partition_value', label:gettext('Partition Scheme'),
-          type: 'text', visible: false,
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }],
-      }),
       canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       // Check to whether table has disable trigger(s)
       canCreate_with_trigger_enable: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
index acc285e99..d1908a6eb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
@@ -88,64 +88,6 @@ define('pgadmin.node.row_security_policy', [
           }
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
-          mode: ['properties']
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode: ['properties'],
-        }],
-        validate: function(keys) {
-          var msg;
-          this.errorModel.clear();
-          // If nothing to validate
-          if (keys && keys.length == 0) {
-            return null;
-          }
-
-          if(_.isUndefined(this.get('name'))
-            || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-          if (!this.isNew() && !_.isNull(this.get('using_orig')) && this.get('using_orig') != '' && String(this.get('using')).replace(/^\s+|\s+$/g, '') == ''){
-            msg = gettext('"USING" can not be empty once the value is set');
-            this.errorModel.set('using', msg);
-            return msg;
-          }
-          if (!this.isNew() && !_.isNull(this.get('withcheck_orig')) && this.get('withcheck_orig') != '' && String(this.get('withcheck')).replace(/^\s+|\s+$/g, '') == ''){
-            msg = gettext('"Withcheck" can not be empty once the value is set');
-            this.errorModel.set('withcheck', msg);
-            return msg;
-          }
-          return null;
-        },
-        disableWithCheck: function(m){
-          var event = m.get('event');
-          if ((event == 'SELECT') || (event == 'DELETE')){
-            m.set('withcheck', '');
-            return true;
-          }
-          return false;
-        },
-
-        disableUsing: function(m){
-          var event = m.get('event');
-
-          if (event == 'INSERT'){
-            return true;
-          }
-          return false;
-        },
-
-      }),
       canCreate: function(itemData, item) {
 
         var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
index cde25009b..73ebd4183 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
@@ -207,54 +207,6 @@ define('pgadmin.node.rule', [
           }
         );
       },
-      /**
-        Define model for the rule node and specify the node
-        properties of the model in schema.
-       */
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'),
-          type: 'text', disabled: function(m) {
-            // disable name field it it is system rule
-            if (m && m.get('name') == '_RETURN') {
-              return true;
-            }
-            if (m.isNew && m.isNew() || m.node_info && m.node_info.server.version >= 90400) {
-              return false;
-            }
-            return true;
-          },
-        },
-        {
-          id: 'oid', label: gettext('OID'),
-          type: 'text', mode: ['properties'],
-        },
-        {
-          id: 'comment', label: gettext('Comment'), cell: 'string', type: 'multiline',
-        },
-        ],
-        validate: function() {
-
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name');
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') === '')
-          {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }
-          else
-          {
-            this.errorModel.unset('name');
-          }
-          return null;
-        },
-      }),
 
       // Show or hide create rule menu option on parent node
       canCreate: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
index 1e4ecba89..c60ecbc5c 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
@@ -187,468 +187,6 @@ define('pgadmin.node.trigger', [
           },
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          is_row_trigger: true,
-          fires: 'BEFORE',
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'int', mode: ['properties'],
-        },{
-          id: 'is_enable_trigger', label: gettext('Trigger enabled?'),
-          mode: ['edit', 'properties'], group: gettext('Definition'),
-          disabled: function() {
-            if(this.node_info && ('catalog' in this.node_info || 'view' in this.node_info)) {
-              return true;
-            }
-            return false;
-          },
-          options: [
-            {label: gettext('Enable'), value: 'O'},
-            {label: gettext('Enable Replica'), value: 'R'},
-            {label: gettext('Enable Always'), value: 'A'},
-            {label: gettext('Disable'), value: 'D'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'is_row_trigger', label: gettext('Row trigger?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['is_constraint_trigger'],
-          disabled: function(m) {
-            // Disabled if table is a partitioned table.
-            if (!m.isNew())
-              return true;
-
-            if (_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
-              _.has(m.node_info.table, 'is_partitioned') &&
-               m.node_info.table.is_partitioned && m.node_info.server.version < 110000
-            )
-            {
-              setTimeout(function(){
-                m.set('is_row_trigger', false);
-              },10);
-
-              return true;
-            }
-
-            // If constraint trigger is set to True then row trigger will
-            // automatically set to True and becomes disable
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                // change it's model value
-                setTimeout(function() { m.set('is_row_trigger', true); }, 10);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Check if it is row trigger then enabled it.
-              var is_row_trigger = m.get('is_row_trigger');
-              if (!_.isUndefined(is_row_trigger) && m.node_info['server']['server_type'] == 'ppas') {
-                return false;
-              }
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'is_constraint_trigger', label: gettext('Constraint trigger?'),
-          type: 'switch',
-          mode: ['create','edit', 'properties'],
-          group: gettext('Definition'),
-          deps: ['tfunction'],
-          disabled: function(m) {
-            // Disabled if table is a partitioned table.
-            var tfunction = m.get('tfunction');
-            if ((_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
-              _.has(m.node_info.table, 'is_partitioned') &&
-                m.node_info.table.is_partitioned) ||
-                _.indexOf(Object.keys(m.node_info), 'view') != -1 ||
-                (m.node_info.server.server_type === 'ppas' &&
-                !_.isUndefined(tfunction) &&
-                 tfunction === 'Inline EDB-SPL')) {
-              setTimeout(function(){
-                m.set('is_constraint_trigger', false);
-              },10);
-
-              return true;
-            }
-
-            return m.inSchemaWithModelCheck.apply(this, [m]);
-          },
-        },{
-          id: 'tgdeferrable', label: gettext('Deferrable?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['is_constraint_trigger'],
-          disabled: function(m) {
-            // If constraint trigger is set to True then only enable it
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                return false;
-              } else {
-                // If value is already set then reset it to false
-                if(m.get('tgdeferrable')) {
-                  setTimeout(function() { m.set('tgdeferrable', false); }, 10);
-                }
-                return true;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'tginitdeferred', label: gettext('Deferred?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['tgdeferrable', 'is_constraint_trigger'],
-          disabled: function(m) {
-            // If Deferrable is set to True then only enable it
-            var tgdeferrable = m.get('tgdeferrable');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(tgdeferrable) &&
-                tgdeferrable) {
-                return false;
-              } else {
-                // If value is already set then reset it to false
-                if(m.get('tginitdeferred')) {
-                  setTimeout(function() { m.set('tginitdeferred', false); }, 10);
-                }
-                // If constraint trigger is set then do not disable
-                return m.get('is_constraint_trigger') ? false : true;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'tfunction', label: gettext('Trigger function'),
-          type: 'text', disabled: 'inSchemaWithModelCheck',
-          mode: ['create','edit', 'properties'], group: gettext('Definition'),
-          control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema',
-          cache_node: 'trigger_function',
-        },{
-          id: 'tgargs', label: gettext('Arguments'), cell: 'string',
-          group: gettext('Definition'),
-          type: 'text',mode: ['create','edit', 'properties'], deps: ['tfunction'],
-          disabled: function(m) {
-            // We will disable it when EDB PPAS and trigger function is
-            // set to Inline EDB-SPL
-            var tfunction = m.get('tfunction'),
-              server_type = m.node_info['server']['server_type'];
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(server_type === 'ppas' &&
-                !_.isUndefined(tfunction) &&
-                  tfunction === 'Inline EDB-SPL') {
-                // Disable and clear its value
-                m.set('tgargs', undefined);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'fires', label: gettext('Fires'), deps: ['is_constraint_trigger'],
-          mode: ['create','edit', 'properties'], group: gettext('Events'),
-          options: function(control) {
-            var table_options = [
-                {label: 'BEFORE', value: 'BEFORE'},
-                {label: 'AFTER', value: 'AFTER'}],
-              view_options = [
-                {label: 'BEFORE', value: 'BEFORE'},
-                {label: 'AFTER', value: 'AFTER'},
-                {label: 'INSTEAD OF', value: 'INSTEAD OF'}];
-            // If we are under table then show table specific options
-            if(_.indexOf(Object.keys(control.model.node_info), 'table') != -1) {
-              return table_options;
-            } else {
-              return view_options;
-            }
-          },
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-          disabled: function(m) {
-            if (!m.isNew())
-              return true;
-            // If contraint trigger is set to True then only enable it
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                setTimeout(function() { m.set('fires', 'AFTER'); }, 10);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Check if it is row trigger then enabled it.
-              var fires_ = m.get('fires');
-              if (!_.isUndefined(fires_) && m.node_info['server']['server_type'] == 'ppas') {
-                return false;
-              }
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          type: 'nested', control: 'fieldset', mode: ['create','edit', 'properties'],
-          label: gettext('Events'), group: gettext('Events'), contentClass: 'row',
-          schema:[{
-            id: 'evnt_insert', label: gettext('INSERT'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_insert = m.get('evnt_insert');
-              if (!_.isUndefined(evn_insert) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_update', label: gettext('UPDATE'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_update = m.get('evnt_update');
-              if (!_.isUndefined(evn_update) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_delete', label: gettext('DELETE'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_delete = m.get('evnt_delete');
-              if (!_.isUndefined(evn_delete) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_truncate', label: gettext('TRUNCATE'),
-            type: 'switch', group: gettext('Events'),deps: ['is_row_trigger', 'is_constraint_trigger'],
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var is_constraint_trigger = m.get('is_constraint_trigger'),
-                is_row_trigger = m.get('is_row_trigger'),
-                server_type = m.node_info['server']['server_type'];
-              if (is_row_trigger == true){
-                setTimeout(function(){
-                  m.set('evnt_truncate', false);
-                },10);
-                return true;
-              }
-
-              if (server_type === 'ppas' &&
-                  !_.isUndefined(is_constraint_trigger) &&
-                    !_.isUndefined(is_row_trigger) &&
-                    is_constraint_trigger === false && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          }],
-        },{
-          id: 'whenclause', label: gettext('When'),
-          type: 'text', disabled: 'inSchemaWithModelCheck',
-          mode: ['create', 'edit', 'properties'],
-          control: 'sql-field', visible: true, group: gettext('Events'),
-        },{
-          id: 'columns', label: gettext('Columns'), url: 'nodes',
-          control: 'node-list-by-name', cache_node: 'column', type: 'array',
-          select2: {'multiple': true},
-          deps: ['evnt_update'], node: 'column', group: gettext('Events'),
-          disabled: function(m) {
-            if(this.node_info &&  'catalog' in this.node_info) {
-              return true;
-            }
-            //Disable in edit mode
-            if (!m.isNew()) {
-              return true;
-            }
-            // Enable column only if update event is set true
-            var isUpdate = m.get('evnt_update');
-            if(!_.isUndefined(isUpdate) && isUpdate) {
-              return false;
-            }
-            return true;
-          },
-        },{
-          id: 'tgoldtable', label: gettext('Old table'),
-          type: 'text', group: gettext('Transition'),
-          cell: 'string', mode: ['create', 'edit', 'properties'],
-          deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
-          disabled: 'disableTransition',
-        },{
-          id: 'tgnewtable', label: gettext('New table'),
-          type: 'text', group: gettext('Transition'),
-          cell: 'string', mode: ['create', 'edit', 'properties'],
-          deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
-          disabled: 'disableTransition',
-        },{
-          id: 'prosrc', label: gettext('Code'), group: gettext('Code'),
-          type: 'text', mode: ['create', 'edit'], deps: ['tfunction'],
-          tabPanelCodeClass: 'sql-code-control',
-          control: Backform.SqlCodeControl,
-          visible: true,
-          disabled: function(m) {
-            // We will enable it only when EDB PPAS and trigger function is
-            // set to Inline EDB-SPL
-            var tfunction = m.get('tfunction'),
-              server_type = m.node_info['server']['server_type'];
-
-            return (server_type !== 'ppas' ||
-            _.isUndefined(tfunction) ||
-              tfunction !== 'Inline EDB-SPL');
-          },
-        },{
-          id: 'is_sys_trigger', label: gettext('System trigger?'), cell: 'string',
-          type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }],
-        validate: function(keys) {
-          var msg;
-          this.errorModel.clear();
-
-          // If nothing to validate
-          if (keys && keys.length == 0) {
-            return null;
-          }
-
-          if(_.isUndefined(this.get('name'))
-            || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-          if(_.isUndefined(this.get('tfunction'))
-            || String(this.get('tfunction')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Trigger function cannot be empty.');
-            this.errorModel.set('tfunction', msg);
-            return msg;
-          }
-
-          if(!this.get('evnt_truncate') && !this.get('evnt_delete') &&
-            !this.get('evnt_update') && !this.get('evnt_insert')) {
-            msg = gettext('Specify at least one event.');
-            this.errorModel.set('evnt_truncate', ' ');
-            this.errorModel.set('evnt_delete', ' ');
-            this.errorModel.set('evnt_update', ' ');
-            this.errorModel.set('evnt_insert', msg);
-            return msg;
-          }
-
-          if(!_.isUndefined(this.get('tfunction')) &&
-            this.get('tfunction') === 'Inline EDB-SPL' &&
-              (_.isUndefined(this.get('prosrc'))
-                || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == ''))
-          {
-            msg = gettext('Trigger code cannot be empty.');
-            this.errorModel.set('prosrc', msg);
-            return msg;
-          }
-          return null;
-        },
-        // We will check if we are under schema node & in 'create' mode
-        inSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          return false;
-        },
-        // We will check if we are under schema node & in 'create' mode
-        inSchemaWithModelCheck: function(m) {
-          if(this.node_info &&  'schema' in this.node_info) {
-            // We will disable control if it's in 'edit' mode
-            return !m.isNew();
-          }
-          return true;
-        },
-        // Checks weather to enable/disable control
-        inSchemaWithColumnCheck: function(m) {
-          if(this.node_info &&  'schema' in this.node_info) {
-            // We will disable control if it's system columns
-            // ie: it's position is less then 1
-            if (m.isNew()) {
-              return false;
-            } else {
-              // if we are in edit mode
-              return (_.isUndefined(m.get('attnum')) || m.get('attnum') < 1 );
-            }
-          }
-          return true;
-        },
-        // Disable/Enable Transition tables
-        disableTransition: function(m) {
-          if (!m.isNew())
-            return true;
-          var flag = false,
-            evnt = null,
-            name = this.name,
-            evnt_count = 0;
-
-          // Disable transition tables for view trigger and PG version < 100000
-          if(_.indexOf(Object.keys(m.node_info), 'table') == -1 ||
-            m.node_info.server.version < 100000) return true;
-
-          if (name == 'tgoldtable') evnt = 'evnt_delete';
-          else if (name == 'tgnewtable') evnt = 'evnt_insert';
-
-          if(m.get('evnt_insert')) evnt_count++;
-          if(m.get('evnt_update')) evnt_count++;
-          if(m.get('evnt_delete')) evnt_count++;
-
-
-          // Disable transition tables if
-          //  - It is a constraint trigger
-          //  - Fires other than AFTER
-          //  - More than one events enabled
-          //  - Update event with the column list
-
-          // Disable Old transition table if both UPDATE and DELETE events are disabled
-          // Disable New transition table if both UPDATE and INSERT events are disabled
-          if(!m.get('is_constraint_trigger') && m.get('fires') == 'AFTER' &&
-            (m.get('evnt_update') || m.get(evnt)) && evnt_count == 1) {
-            flag = (m.get('evnt_update') && (_.size(m.get('columns')) >= 1 && m.get('columns')[0] != ''));
-          }
-
-          flag && setTimeout(function() {
-            if(m.get(name)) {
-              m.set(name, null);
-            }
-          },10);
-
-          return flag;
-        },
-      }),
       canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       // Check to whether trigger is disable ?
       canCreate_with_trigger_enable: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
index f0ec287f0..56ef198e1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
@@ -74,48 +74,6 @@ define('pgadmin.node.type', [
 
       },
       ext_funcs: undefined,
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          is_sys_type: false,
-          typtype: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user,
-              schemaInfo = args.node_info.schema;
-
-            this.set({
-              'typeowner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'schemaCheck',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'typeowner', label: gettext('Owner'), cell: 'string',
-          control: 'node-list-by-name',
-          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
-          disabled: 'inSchema', select2: {allowClear: false},
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }]
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['type'];
         return new TypeSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
index 393707c9b..cbfd68667 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
@@ -146,93 +146,6 @@ define('pgadmin.node.mview', [
           }
         );
       },
-      /**
-        Define model for the view node and specify the
-        properties of the model in schema.
-       */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            // Set Selected Schema and Current User
-            var schemaLabel = args.node_info.schema._label || 'public',
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'schema': schemaLabel, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          spcname: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          control: 'node-list-by-name', select2: { allowClear: false },
-          node: 'role', disabled: 'inSchema',
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-        sessChanged: function() {
-          /* If only custom autovacuum option is enabled the check if the options table is also changed. */
-          if(_.size(this.sessAttrs) == 2 && this.sessAttrs['autovacuum_custom'] && this.sessAttrs['toast_autovacuum']) {
-            return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
-          }
-          if(_.size(this.sessAttrs) == 1 && (this.sessAttrs['autovacuum_custom'] || this.sessAttrs['toast_autovacuum'])) {
-            return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
-          }
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-        validate: function(keys) {
-
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name'),
-            field_def = this.get('definition');
-
-          if(_.indexOf(keys, 'autovacuum_custom'))
-            if (_.indexOf(keys, 'autovacuum_enabled') != -1 ||
-              _.indexOf(keys, 'toast_autovacuum_enabled') != -1 )
-              return null;
-
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('name');
-          }
-          if (_.isUndefined(field_def) || _.isNull(field_def) ||
-            String(field_def).replace(/^\s+|\s+$/g, '') == '') {
-            err['definition'] = gettext('Please enter view definition.');
-            errmsg = err['definition'];
-            this.errorModel.set('definition', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('definition');
-          }
-          return null;
-        },
-        // We will disable everything if we are under catalog node
-        inSchema: function() {
-          if(this.node_info && 'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-
-      }),
 
       refresh_mview: function(args) {
         var input = args || {},
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
index b98ea6c6c..0ba952954 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
@@ -108,163 +108,6 @@ define('pgadmin.node.view', [
           }
         );
       },
-      /**
-        Define model for the view node and specify the
-        properties of the model in schema.
-      */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            // Set Selected Schema and, Current User
-            var schemaLabel = args.node_info.schema._label || 'public',
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'schema': schemaLabel, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'notInSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string', control: 'node-list-by-name',
-          node: 'role', disabled: 'notInSchema', select2: { allowClear: false },
-        },{
-          id: 'schema', label: gettext('Schema'), cell: 'string', first_empty: false,
-          control: 'node-list-by-name', type: 'text', cache_level: 'database',
-          node: 'schema', disabled: 'notInSchema', mode: ['create', 'edit'],
-          select2: { allowClear: false }, cache_node: 'database',
-        },{
-          id: 'system_view', label: gettext('System view?'), cell: 'string',
-          type: 'switch', mode: ['properties'],
-        },{
-          id: 'acl', label: gettext('Privileges'),
-          mode: ['properties'], type: 'text', group: gettext('Security'),
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'notInSchema',
-        },{
-          id: 'security_barrier', label: gettext('Security barrier?'),
-          type: 'switch', min_version: '90200', group: gettext('Definition'),
-          disabled: 'notInSchema',
-        },{
-          id: 'check_option', label: gettext('Check options'),
-          control: 'select2', group: gettext('Definition'), type: 'text',
-          min_version: '90400', mode:['properties', 'create', 'edit'],
-          select2: {
-            // Set select2 option width to 100%
-            allowClear: false,
-          }, disabled: 'notInSchema',
-          options:[{
-            label: gettext('No'), value: 'no',
-          },{
-            label: gettext('Local'), value: 'local',
-          },{
-            label: gettext('Cascaded'), value: 'cascaded',
-          }],
-        },{
-          id: 'definition', label: gettext('Code'), cell: 'string',
-          type: 'text', mode: ['create', 'edit'], group: gettext('Code'),
-          tabPanelCodeClass: 'sql-code-control',
-          disabled: 'notInSchema',
-          control: Backform.SqlCodeControl.extend({
-            onChange: function() {
-              Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
-
-              if (!this.model || !(
-                this.model.changed &&
-                this.model.node_info.server.server_type == 'pg' &&
-                // No need to check this when creating a view
-                this.model.get('oid') !== undefined
-              ) || !(
-                this.model.origSessAttrs &&
-                this.model.changed.definition != this.model.origSessAttrs.definition
-              )) {
-                this.model.warn_text = undefined;
-                return;
-              }
-
-              let old_def = this.model.origSessAttrs.definition &&
-                this.model.origSessAttrs.definition.replace(
-                  /\s/gi, ''
-                ).split('FROM'),
-                new_def = [];
-
-              if (this.model.changed.definition !== undefined) {
-                new_def = this.model.changed.definition.replace(
-                  /\s/gi, ''
-                ).split('FROM');
-              }
-
-              if ((old_def.length != new_def.length) || (
-                old_def.length > 1 && (
-                  old_def[0] != new_def[0]
-                )
-              )) {
-                this.model.warn_text = gettext(
-                  'Changing the columns in a view requires dropping and re-creating the view. This may fail if other objects are dependent upon this view, or may cause procedural functions to fail if they are not modified to take account of the changes.'
-                ) + '<br><br><b>' + gettext('Do you wish to continue?') +
-                '</b>';
-              } else {
-                this.model.warn_text = undefined;
-              }
-            },
-          }),
-        }, pgBrowser.SecurityGroupSchema, {
-          // Add Privilege Control
-          id: 'datacl', label: gettext('Privileges'), type: 'collection',
-          model: pgBrowser.Node.PrivilegeRoleModel.extend({
-            privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't'],
-          }), uniqueCol : ['grantee'], editable: false, group: 'security',
-          mode: ['edit', 'create'], canAdd: true, canDelete: true,
-          control: 'unique-col-collection', disabled: 'notInSchema',
-        },{
-          // Add Security Labels Control
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
-          canEdit: false, group: 'security', canDelete: true,
-          mode: ['edit', 'create'], canAdd: true, disabled: 'notInSchema',
-          control: 'unique-col-collection', uniqueCol : ['provider'],
-        }],
-        validate: function() {
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name'),
-            field_def = this.get('definition');
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('name');
-          }
-          if (_.isUndefined(field_def) || _.isNull(field_def) ||
-            String(field_def).replace(/^\s+|\s+$/g, '') == '') {
-            err['definition'] = gettext('Please enter view code.');
-            errmsg = err['definition'];
-            this.errorModel.set('definition', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('definition');
-          }
-          return null;
-        },
-        // We will disable everything if we are under catalog node
-        notInSchema: function() {
-          if(this.node_info && 'catalog' in this.node_info) {
-            return true;
-          }
-          return false;
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
index 344abcac5..a60fc26d9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
@@ -351,45 +351,6 @@ define('pgadmin.node.database', [
           }
         );
       },
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'did',
-        defaults: {
-          name: undefined,
-          owner: undefined,
-          comment: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'datowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [
-          {
-            id: 'name', label: gettext('Database'), cell: 'string',
-            editable: false, type: 'text',
-          },{
-            id: 'did', label: gettext('OID'), cell: 'string', mode: ['properties'],
-            editable: false, type: 'text',
-          },{
-            id: 'datowner', label: gettext('Owner'),
-            editable: false, type: 'text', node: 'role',
-            control: Backform.NodeListByNameControl, select2: { allowClear: false },
-          },{
-            id: 'comments', label: gettext('Comment'),
-            editable: false, type: 'multiline',
-          },
-        ],
-      }),
     });
 
     pgBrowser.SecurityGroupSchema = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
index 0715ea1b7..5b02716d3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
@@ -95,20 +95,20 @@ export default class DatabaseSchema extends BaseUISchema {
     return [
       {
         id: 'name', label: gettext('Database'), cell: 'text',
-        editable: false, type: 'text', noEmpty: true,
+        editable: false, type: 'text', noEmpty: true, isCollectionProperty: true,
       },{
         id: 'did', label: gettext('OID'), cell: 'text', mode: ['properties'],
         editable: false, type: 'text',
       },{
         id: 'datowner', label: gettext('Owner'),
         editable: false, type: 'select', options: this.fieldOptions.role,
-        controlProps: { allowClear: false },
+        controlProps: { allowClear: false }, isCollectionProperty: true,
       },{
         id: 'is_sys_obj', label: gettext('System database?'),
         cell: 'switch', type: 'switch', mode: ['properties'],
       },{
         id: 'comments', label: gettext('Comment'),
-        editable: false, type: 'multiline',
+        editable: false, type: 'multiline', isCollectionProperty: true,
       },{
         id: 'encoding', label: gettext('Encoding'),
         editable: false, type: 'select', group: gettext('Definition'),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
index 1a145b4d6..f5f596188 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
@@ -14,8 +14,8 @@ import Notify from '../../../../../../../static/js/helpers/Notifier';
 
 define('pgadmin.node.subscription', [
   'sources/gettext', 'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for subscriptions collection
   if (!pgBrowser.Nodes['coll-subscription']) {
@@ -24,7 +24,7 @@ define('pgadmin.node.subscription', [
         node: 'subscription',
         label: gettext('Subscriptions'),
         type: 'coll-subscription',
-        columns: ['name', 'subowner', 'pub', 'enabled'],
+        columns: ['name', 'subowner', 'proppub', 'enabled'],
         hasStatistics: true,
       });
   }
@@ -74,101 +74,6 @@ define('pgadmin.node.subscription', [
           enable: 'canCreate',
         }]);
       },
-      // Define the model for subscription node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          subowner: undefined,
-          pubtable: undefined,
-          connect_timeout: 10,
-          pub:[],
-          enabled:true,
-          create_slot: true,
-          copy_data:true,
-          connect:true,
-          copy_data_after_refresh:false,
-          sync:'off',
-          refresh_pub: false,
-          password: '',
-          sslmode: 'prefer',
-          sslcompression: false,
-          sslcert: '',
-          sslkey: '',
-          sslrootcert: '',
-          sslcrl: '',
-          host: '',
-          hostaddr: '',
-          port: 5432,
-          db: 'postgres',
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'subowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the subscription node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-          visible: function() {
-            if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
-              && !_.isUndefined(this.node_info.server.version) &&
-                this.node_info.server.version >= 100000) {
-              return true;
-            }
-            return false;
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },
-        {
-          id: 'subowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
-          disabled: function(m){
-            if(m.isNew())
-              return true;
-            return false;
-          },
-        },
-        {
-          id: 'enabled', label: gettext('Enabled?'),
-          type: 'switch', mode: ['properties'],
-          group: gettext('With'),
-          readonly: 'isConnect', deps :['connect'],
-          helpMessage: gettext('Specifies whether the subscription should be actively replicating, or whether it should be just setup but not started yet.'),
-        },
-        {
-          id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
-          mode: ['properties'],
-        },
-        ],
-        sessChanged: function() {
-          if (!this.isNew() && _.isUndefined(this.attributes['refresh_pub']))
-            return false;
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-        canCreate: function(itemData, item) {
-          var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
-            server = treeData['server'];
-
-          // If server is less than 10 then do not allow 'create' menu
-          if (server && server.version < 100000)
-            return false;
-
-          // by default we want to allow create menu
-          return true;
-        },
-      }),
       getSchema: function(treeNodeInfo, itemNodeData){
         return new SubscriptionSchema(
           {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
index bb6b418c6..771e3c03b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
@@ -176,7 +176,7 @@ export default class SubscriptionSchema extends BaseUISchema{
       mode: ['properties', 'edit', 'create'],
     },
     {
-      id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
+      id: 'proppub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
       mode: ['properties'],
     },
     {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
index f7a6baf3b..a416821da 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
@@ -1,6 +1,7 @@
 SELECT  sub.oid as oid,
         subname as name,
         subpublications as pub,
+        subpublications as proppub,
         sub.subsynccommit as sync,
         pga.rolname as subowner,
         subslotname as slot_name,
diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
index 1147e352c..0b037813c 100644
--- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
+++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
@@ -582,152 +582,6 @@ define('pgadmin.node.role', [
           },
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          oid: null,
-          rolname: undefined,
-          rolcanlogin: false,
-          rolconnlimit: -1,
-          rolsuper: false,
-          rolcreaterole: false,
-          rolcreatedb: false,
-          rolinherit: true,
-          rolcatupdate: false,
-          rolreplication: false,
-          rolvaliduntil: null,
-        },
-        schema: [{
-          id: 'rolname', label: gettext('Name'), type: 'text',
-          readonly: 'readonly',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          editable: false, type: 'text', visible: true,
-        },{
-          id: 'rolvaliduntil', readonly: 'readonly', type: 'text',
-          group: gettext('Definition'), label: gettext('Account expires'),
-          mode: ['properties', 'edit', 'create'], control: 'datetimepicker',
-          deps: ['rolcanlogin'],
-          placeholder: gettext('No Expiry'),
-          helpMessage: gettext('Please note that if you leave this field blank, then password will never expire.'),
-          setMinDate: false,
-        },{
-          id: 'rolconnlimit',  type: 'int', group: gettext('Definition'),
-          label: gettext('Connection limit'), cell: 'integer', min : -1,
-          mode: ['properties', 'edit', 'create'], readonly: 'readonly',
-        },{
-          id: 'rolcanlogin', label: gettext('Can login?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          group: gettext('Privileges'),
-          readonly: 'readonly',
-        },{
-          id: 'rolsuper', label: gettext('Superuser?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          group: gettext('Privileges'),
-          control: Backform.SwitchControl.extend({
-            onChange: function() {
-              Backform.SwitchControl.prototype.onChange.apply(this, arguments);
-
-              this.model.set('rolcatupdate', this.model.get('rolsuper'));
-              this.model.set('rolcreaterole', this.model.get('rolsuper'));
-              this.model.set('rolcreatedb', this.model.get('rolsuper'));
-            },
-          }),
-          readonly: 'readonly',
-        },{
-          id: 'rolcreaterole', label: gettext('Create roles?'),
-          group: gettext('Privileges'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'is_sys_obj', label: gettext('System role?'),
-          cell:'boolean', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comments'), type: 'multiline',
-          group: null, mode: ['properties', 'edit', 'create'],
-          readonly: 'readonly',
-        },{
-          id: 'rolcreatedb', label: gettext('Create databases?'),
-          group: gettext('Privileges'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'rolcatupdate', label: gettext('Update catalog?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          max_version: 90400,
-          group: gettext('Privileges'), readonly: function(m) {
-            return m.get('read_only');
-          },
-          disabled: function(m) {
-            return !m.get('rolsuper');
-          },
-        },{
-          id: 'rolinherit', group: gettext('Privileges'),
-          label: gettext('Inherit rights from the parent roles?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'rolreplication', group: gettext('Privileges'),
-          label: gettext('Can initiate streaming replication and backups?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          min_version: 90100,
-          readonly: 'readonly',
-        }],
-        readonly: function(m) {
-          if (!m.has('read_only')) {
-            var user = this.node_info.server.user;
-
-            m.set('read_only', !(user.is_superuser || user.can_create_role));
-          }
-
-          return m.get('read_only');
-        },
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('rolname')) || String(this.get('rolname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index 9e6d3d543..7ee989122 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -9,6 +9,11 @@
 
 import {getNodeView, removeNodeView} from './node_view';
 import Notify from '../../../static/js/helpers/Notifier';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Theme from 'sources/Theme';
+
+import {CollectionNodeView} from '../../../../pgadmin/misc/properties/CollectionNodeProperties';
 
 define('pgadmin.browser.node', [
   'sources/url_for',
@@ -1072,7 +1077,8 @@ define('pgadmin.browser.node', [
         // + Statistics
         var b = browser || pgBrowser,
           t = b.tree,
-          d = data || t.itemData(item);
+          d = data || t.itemData(item),
+          node = item && d && pgBrowser.Nodes[d._type];
 
         // Update the menu items
         pgAdmin.Browser.enable_disable_menus.apply(b, [item]);
@@ -1084,7 +1090,26 @@ define('pgadmin.browser.node', [
             b.panels['properties'].panel.isVisible()) {
             // Show object properties (only when the 'properties' tab
             // is active).
-            this.showProperties(item, d, b.panels['properties'].panel);
+            let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
+
+            if (d._type.includes('coll-')){
+              b.panels['properties'].panel.$container.removeClass('pg-panel-content pg-no-overflow pg-el-container');
+
+              ReactDOM.render(
+                <Theme>
+                  <CollectionNodeView
+                    node={node}
+                    treeNodeInfo={treeNodeInfo}
+                    item={item}
+                    itemNodeData={d}
+                    pgBrowser={pgBrowser}
+                  ></CollectionNodeView>
+                </Theme>,
+                b.panels['properties'].panel.$container[0]
+              );
+            }else{
+              this.showProperties(item, d, b.panels['properties'].panel);
+            }
           }
         }
 
@@ -1259,20 +1284,20 @@ define('pgadmin.browser.node', [
             d = i && tree.itemData(i),
             treeHierarchy = tree.getTreeNodeHierarchy(i);
 
-          if (_.isEqual($(this).data('node-prop'), treeHierarchy)) {
-            return;
-          }
-
           // Cache the current IDs for next time
           $(this).data('node-prop', treeHierarchy);
 
           /* Remove any dom rendered by getNodeView */
-          removeNodeView(j[0]);
-          /* getSchema is a schema for React. Get the react node view */
+          removeNodeView(pgBrowser.panels['properties'].panel.$container[0]);
+
+          var containerProperties =  pgBrowser.panels['properties'].panel.$container;
+          containerProperties.addClass('pg-panel-content pg-no-overflow pg-el-container');
+
+
           if(that.getSchema) {
             let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
             getNodeView(
-              that.type, treeNodeInfo, 'properties', data, 'tab', j[0], this, onEdit
+              that.type, treeNodeInfo, 'properties', data, 'tab', containerProperties[0], this, onEdit
             );
             return;
           }
diff --git a/web/pgadmin/browser/static/js/node_ajax.js b/web/pgadmin/browser/static/js/node_ajax.js
index 14a9afa3c..19ac76562 100644
--- a/web/pgadmin/browser/static/js/node_ajax.js
+++ b/web/pgadmin/browser/static/js/node_ajax.js
@@ -25,8 +25,9 @@ export function generateCollectionURL(item, type) {
   };
   var treeInfo = pgAdmin.Browser.tree.getTreeNodeHierarchy(item);
   var actionType = type in opURL ? opURL[type] : type;
+  var nodeType = type === 'properties' ? nodeObj.type : nodeObj.node;
   return generate_url(
-    pgAdmin.Browser.URL, treeInfo, actionType, nodeObj.node,
+    pgAdmin.Browser.URL, treeInfo, actionType, nodeType,
     collectionPickFunction
   );
 }
diff --git a/web/pgadmin/browser/static/js/node_view.jsx b/web/pgadmin/browser/static/js/node_view.jsx
index b9ec79e90..453f20c95 100644
--- a/web/pgadmin/browser/static/js/node_view.jsx
+++ b/web/pgadmin/browser/static/js/node_view.jsx
@@ -16,7 +16,6 @@ import {getHelpUrl, getEPASHelpUrl} from 'pgadmin.help';
 import SchemaView from 'sources/SchemaView';
 import { generateNodeUrl } from './node_ajax';
 import Notify from '../../../static/js/helpers/Notifier';
-
 import gettext from 'sources/gettext';
 import 'wcdocker';
 
diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js
index fbbc56bd5..1aa4a73ac 100644
--- a/web/pgadmin/browser/static/js/panel.js
+++ b/web/pgadmin/browser/static/js/panel.js
@@ -122,16 +122,56 @@ define(
                 that.resizedContainer.apply(myPanel);
               }
 
-              // Bind events only if they are configurable
-              if (that.canHide) {
-                _.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
-                  function(ev) {
-                    myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
-                  });
+
+
+              if (myPanel._type == 'dashboard') {
+                getPanelView(
+                  pgBrowser.tree,
+                  $container[0],
+                  pgBrowser,
+                  myPanel._type
+                );
               }
 
+              // Bind events only if they are configurable
+              // if (that.canHide) {
+              _.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
+                function(ev) {
+                  myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
+                });
+              // }
+
               pgBrowser.Events.on('pgadmin-browser:tree:selected', () => {
 
+                if(myPanel.isVisible()) {
+                  // removePanelView($container[0]);
+                  getPanelView(
+                    pgBrowser.tree,
+                    $container[0],
+                    pgBrowser,
+                    myPanel._type
+                  );
+                }
+              });
+              // pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
+
+              //     removePanelView($container[0]);
+              // });
+
+              // pgBrowser.Events.on('pgadmin:browser:node:updated', () => {
+
+              //   if(myPanel.isVisible()) {
+              //     getPanelView(
+              //       pgBrowser.tree,
+              //       $container[0],
+              //       pgBrowser,
+              //       myPanel._type
+              //     );
+              //   }
+              // });
+
+              pgBrowser.Events.on('pgadmin-browser:tree:refreshing', () => {
+
                 if(myPanel.isVisible()) {
                   getPanelView(
                     pgBrowser.tree,
@@ -206,10 +246,9 @@ define(
       },
       handleVisibility: function(eventName) {
         // Supported modules
-        let type_module = {
-          dashboard: pgAdmin.Dashboard,
-        };
-        let module = type_module[this._type];
+        // let type_module = {
+        //   dashboard: pgAdmin.Dashboard,
+        // };
         if (_.isNull(pgBrowser.tree)) return;
 
         let selectedPanel = pgBrowser.docker.findPanels(this._type)[0];
@@ -219,17 +258,17 @@ define(
           .scene()
           .find('.pg-panel-content');
 
-        if (this._type === 'dashboard') {
-          if (eventName == 'panelClosed') {
-            module.toggleVisibility.call(module, false, true);
-          } else if (eventName == 'panelVisibilityChanged') {
-            module.toggleVisibility.call(
-              module,
-              pgBrowser.docker.findPanels(this._type)[0].isVisible(),
-              false
-            );
-          }
-        }
+        // if (this._type === 'dashboard') {
+        //   if (eventName == 'panelClosed') {
+        //     module.toggleVisibility.call(module, false, true);
+        //   } else if (eventName == 'panelVisibilityChanged') {
+        //     module.toggleVisibility.call(
+        //       module,
+        //       pgBrowser.docker.findPanels(this._type)[0].isVisible(),
+        //       false
+        //     );
+        //   }
+        // }
 
         if (isPanelVisible) {
           if (eventName == 'panelClosed') {
diff --git a/web/pgadmin/browser/static/js/panel_view.jsx b/web/pgadmin/browser/static/js/panel_view.jsx
index cf0a5a07e..0c5e18549 100644
--- a/web/pgadmin/browser/static/js/panel_view.jsx
+++ b/web/pgadmin/browser/static/js/panel_view.jsx
@@ -13,6 +13,11 @@ import Theme from 'sources/Theme';
 import Dependencies from '../../../misc/dependencies/static/js/Dependencies';
 import Dependents from '../../../misc/dependents/static/js/Dependents';
 import Statistics from '../../../misc/statistics/static/js/Statistics';
+import SQL from '../../../misc/sql/static/js/Sql';
+import Dashboard from '../../../dashboard/static/js/Dashboard';
+import _ from 'lodash';
+import { CollectionNodeView } from '../../../misc/properties/CollectionNodeProperties';
+
 
 /* The entry point for rendering React based view in properties, called in node.js */
 export function getPanelView(
@@ -21,10 +26,33 @@ export function getPanelView(
   pgBrowser,
   panelType
 ) {
-  let item = tree.selected(),
-    nodeData = item && tree.itemData(item),
-    node = item && nodeData && pgBrowser.Nodes[nodeData._type],
+  let item = !_.isNull(tree)? tree.selected(): null,
+
+    nodeData, node, treeNodeInfo, preferences;
+  if (item){
+    nodeData = tree.itemData(item);
+    node = nodeData && pgBrowser.Nodes[nodeData._type];
     treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
+    preferences = pgBrowser.get_preferences_for_module('dashboards');
+  }
+  if (panelType == 'dashboard') {
+    ReactDOM.render(
+      <Theme>
+        <Dashboard
+          treeNodeInfo={treeNodeInfo}
+          pgBrowser={pgBrowser}
+          nodeData={nodeData}
+          node={node}
+          item={item}
+          preferences={preferences}
+          did={((!_.isUndefined(treeNodeInfo)) && (!_.isUndefined(treeNodeInfo['database']))) && treeNodeInfo['database']._id}
+          sid={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo['server']._id : ''}
+          serverConnected={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo.server.connected: false}
+        />
+      </Theme>,
+      container
+    );
+  }
 
 
   if (panelType == 'statistics') {
@@ -41,6 +69,20 @@ export function getPanelView(
       container
     );
   }
+  if (panelType == 'properties') {
+    ReactDOM.render(
+      <Theme>
+        <CollectionNodeView
+          treeNodeInfo={treeNodeInfo}
+          item={item}
+          itemNodeData={nodeData}
+          node={node}
+          pgBrowser={pgBrowser}
+        />
+      </Theme>,
+      container
+    );
+  }
   if (panelType == 'dependencies') {
     ReactDOM.render(
       <Theme>
@@ -69,6 +111,20 @@ export function getPanelView(
       container
     );
   }
+  if (panelType == 'sql') {
+    ReactDOM.render(
+      <Theme>
+        <SQL
+          treeNodeInfo={treeNodeInfo}
+          pgBrowser={pgBrowser}
+          nodeData={nodeData}
+          node={node}
+          item={item}
+        />
+      </Theme>,
+      container
+    );
+  }
 }
 
 /* When switching from normal node to collection node, clean up the React mounted DOM */
diff --git a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
new file mode 100644
index 000000000..b8a500aea
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
@@ -0,0 +1,64 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+
+export default class ActiveQuery extends BaseUISchema {
+  constructor(initValues) {
+    super({
+      ...initValues,
+    });
+
+  }
+
+  get baseFields() {
+
+    return [
+
+      {
+        id: 'backend_type',
+        label: gettext('Backend type'),
+        type: 'text',
+        editable: true,
+        noEmpty: true,
+        readonly: true,
+        mode: ['properties'],
+        group: gettext('Details'),
+      },
+      {
+        id: 'query_start',
+        label: gettext('Query started at'),
+        type: 'text',
+        editable: false,
+        readonly: true,
+        group: gettext('Details'),
+      },
+      {
+        id: 'state_change',
+        label: gettext('Last state changed at'),
+        type: 'text',
+        editable: true,
+        readonly: true,
+        group: gettext('Details'),
+      },
+      {
+        id: 'query',
+        label: gettext('SQL'),
+        type: 'text',
+        editable: true,
+        readonly: true,
+        control: 'sql',
+        group: gettext('Details'),
+      },
+    ];
+
+  }
+
+}
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
new file mode 100644
index 000000000..67bcd83c4
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -0,0 +1,868 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+// eslint-disable-next-line react/display-name
+import React, { useEffect, useState} from 'react';
+import gettext from 'sources/gettext';
+import PropTypes from 'prop-types';
+import getApiInstance from 'sources/api_instance';
+import PgTable from 'sources/components/PgTable';
+import { makeStyles } from '@material-ui/core/styles';
+import url_for from 'sources/url_for';
+import Graphs from './Graphs';
+import Notify from '../../../static/js/helpers/Notifier';
+import { Box, Tab, Tabs } from '@material-ui/core';
+import { PgIconButton } from '../../../static/js/components/Buttons';
+import CancelIcon from '@mui/icons-material/Cancel';
+import SquareIcon from '@mui/icons-material/Square';
+import ArrowRightOutlinedIcon from '@mui/icons-material/ArrowRightOutlined';
+import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';
+
+import WelcomeDashboard from './WelcomeDashboard';
+
+import ActiveQuery from './ActiveQuery.ui';
+
+
+function parseData(data) {
+  var res = [];
+
+  data.forEach((row) => {
+    res.push({ ...row, icon: '' });
+  });
+  return res;
+}
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    height: '100%',
+    background: theme.palette.grey[400],
+    overflow: 'hidden',
+    padding: '8px',
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1
+
+  },
+  cardHeader: {
+    padding: '0.25rem 0.5rem',
+    fontWeight: 'bold',
+    backgroundColor: '#fff',
+    color: '#222222',
+    borderColor: '#dde0e6'
+  },
+  searchPadding: {
+    display: 'flex',
+    flex: 2.5,
+  },
+  component: {
+    padding: '8px',
+    flexGrow: 1,
+    minHeight: 0
+  },
+  searchInput: {
+    flex: 1,
+    // marginTop: 2,
+    // borderLeft: "none",
+    // paddingLeft: 5,
+  },
+  panelIcon: {
+    width: '80%',
+    margin: '0 auto',
+    marginTop: '25px !important',
+    position: 'relative',
+    textAlign: 'center',
+  },
+  panelMessage: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+  },
+  panelContent: {
+    margin: 0,
+    // padding: theme.spacing(0.5),
+    // ...theme.mixins.panelBorder.top,
+    // ...theme.mixins.panelBorder.left,
+    border: '2px solid #dde0e6',
+    // display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+    overflow: 'auto'
+    // maxHeight: '10000px'
+  },
+  autoResizer: {
+    width: '100% !important',
+    height: '100% !important',
+    minWidth: '100%',
+    paddingTop: '6px',
+    minHeight: '10% !important',
+    // maxHeight:'1000px !important',
+    // overflowy: 'hidden !important',
+  },
+}));
+
+/* eslint-disable react/display-name */
+export default function Dashboard({
+  nodeData,
+  node,
+  item,
+  pgBrowser,
+  preferences,
+  sid,
+  did,
+  ...props
+}) {
+  const classes = useStyles();
+  let tab = ['Sessions', 'Lock', 'Prepared Transactions'];
+
+  const [dashData, setdashData] = useState([]);
+  const [msg, setMsg] = useState('');
+  const [val, setVal] = useState(0);
+  const [schema, setSchema] = React.useState();
+
+  if (!did) {
+    tab.push('Configuration');
+  }
+
+  const tabChanged = (e, tabVal) => {
+    setVal(tabVal);
+  };
+
+  const serverConfigColumns = React.useMemo(() => [
+    {
+      accessor: 'name',
+      Header: gettext('Name'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'category',
+      Header: gettext('Category'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'setting',
+      Header: gettext('Setting'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'unit',
+      Header: gettext('Unit'),
+      editable: false,
+      cell: 'string',
+    },
+    {
+      accessor: 'short_desc',
+      Header: gettext('Description'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ], [val]);
+
+  const activityColumns = [
+    {
+      accessor: 'terminate_query',
+      Header: ' ',
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 44,
+      // eslint-disable-next-line react/display-name
+      Cell: ({row})=>{
+        var terminate_session_url =
+          url_for('dashboard.index') +
+          'terminate_session' +
+          '/' +
+          sid,
+          title = gettext('Terminate Session?'),
+          txtConfirm = gettext(
+            'Are you sure you wish to terminate the session?'
+          ),
+          txtSuccess = gettext('Session terminated successfully.'),
+          txtError = gettext(
+            'An error occurred whilst terminating the active query.'
+          ),
+          action_url = did ? terminate_session_url + '/' + did : terminate_session_url;
+
+        const api = getApiInstance();
+
+        return (
+          <PgIconButton
+            variant="outlined"
+            icon={<CancelIcon fontSize="small" sx={{ color: '#d11616' }} />}
+            onClick={() => {
+              if (
+                !canTakeAction(
+                  row,
+                  'terminate',
+                  nodeData,
+                  props.treeNodeInfo
+                )
+              )
+                return;
+              action_url += '/' + row.values.pid;
+              Notify.confirm(
+                title,
+                txtConfirm,
+                function () {
+                  api
+                    .delete(action_url)
+                    .then(function (res) {
+                      if (res == gettext('Success')) {
+                        Notify.success(txtSuccess);
+                      } else {
+                        Notify.error(txtError);
+                      }
+                    })
+                    .catch(function (error) {
+                      Notify.alert(
+                        gettext('Failed to retrieve data from the server.'),
+                        gettext(error.message)
+                      );
+                    });
+                },
+                function () {
+                  return true;
+                }
+              );
+            }}
+            color="default"
+            aria-label="Terminate Session?"
+            title={gettext('Terminate Session?')}
+          ></PgIconButton>
+        );
+      },
+    },
+    {
+      accessor: 'cancel_Query',
+      Header: ' ',
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 44,
+      Cell: ({ row }) => {
+        var cancel_query_url =
+          url_for('dashboard.index') + 'cancel_query' + '/' + sid ,
+          title = gettext('Cancel Active Query?'),
+          txtConfirm = gettext(
+            'Are you sure you wish to cancel the active query?'
+          ),
+          txtSuccess = gettext('Active query cancelled successfully.'),
+          txtError = gettext(
+            'An error occurred whilst cancelling the active query.'
+          ),
+          action_url = did ? cancel_query_url + '/' + did : cancel_query_url;
+        
+        const api = getApiInstance();
+
+        return (
+          <PgIconButton
+            variant="outlined"
+            icon={<SquareIcon fontSize="small" />}
+            onClick={() => {
+              if (
+                !canTakeAction(
+                  row,
+                  'cancel',
+                  nodeData,
+                  props.treeNodeInfo                )
+              )
+                return;
+              action_url += '/' + row.values.pid;
+              Notify.confirm(
+                title,
+                txtConfirm,
+                function () {
+                  api
+                    .delete(action_url)
+                    .then(function (res) {
+                      if (res == gettext('Success')) {
+                        Notify.success(txtSuccess);
+                      } else {
+                        Notify.error(txtError);
+                      }
+                    })
+                    .catch(function (error) {
+                      Notify.alert(
+                        gettext('Failed to retrieve data from the server.'),
+                        gettext(error.message)
+                      );
+                    });
+                },
+                function () {
+                  return true;
+                }
+              );
+            }}
+            color="default"
+            aria-label="Cancel the query"
+            title={gettext('Cancel the active query')}
+          ></PgIconButton>
+        );
+      },
+    },
+    {
+      accessor: 'view_active_query',
+      Header: ' ',
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 44,
+      Cell: ({ row }) => {
+
+
+        let canEditRow = true;
+        return (
+          <PgIconButton
+            icon={row.isExpanded ? <ArrowDropDownOutlinedIcon fontSize="small" /> : <ArrowRightOutlinedIcon fontSize="small" />}
+            onClick={() => {
+              row.toggleRowExpanded(!row.isExpanded);
+              setSchema(
+                new ActiveQuery({
+                  query: row.original.query,
+                  backend_type: row.original.backend_type,
+                  state_change: row.original.state_change,
+                  query_start: row.original.query_start,
+                })
+              );
+            }}
+            disabled={!canEditRow}
+            color="default"
+            aria-label="View the active session details"
+            title={gettext('View the active session details')}
+          />
+        );
+      },
+    },
+    {
+      accessor: 'pid',
+      Header: gettext('PID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'usename',
+      Header: gettext('User'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 80,
+    },
+    {
+      accessor: 'application_name',
+      Header: gettext('Application'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'client_addr',
+      Header: gettext('Client'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'backend_start',
+      Header: gettext('Backend start'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'state',
+      Header: gettext('State'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+
+    {
+      accessor: 'waiting',
+      Header: gettext('Waiting'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'wait_event',
+      Header: gettext('Wait event'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'blocking_pids',
+      Header: gettext('Blocking PIDs'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const databaseLocksColumns = [
+    {
+      accessor: 'pid',
+      Header: gettext('PID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'locktype',
+      Header: gettext('Lock type'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'relation',
+      Header: gettext('Target relation'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'page',
+      Header: gettext('Page'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'tuple',
+      Header: gettext('Tuple'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'virtualxid',
+      Header: gettext('vXID (target)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'transactionid',
+      Header: gettext('XID (target)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'classid',
+      Header: gettext('Class'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 40,
+    },
+    {
+      accessor: 'objid',
+      Header: gettext('Object ID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'virtualtransaction',
+      Header: gettext('vXID (owner)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'mode',
+      Header: gettext('Mode'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'granted',
+      Header: gettext('Granted?'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    // {
+    //   accessor: "datname",
+    //   Header: gettext("DB Name?"),
+    //   sortble: true,
+    //   resizable: false,
+    //   disableGlobalFilter: false,
+    // },
+    // {
+    //   accessor: "fastpath",
+    //   Header: gettext("fastpath?"),
+    //   sortble: true,
+    //   resizable: false,
+    //   disableGlobalFilter: false,
+    // },
+    // {
+    //   accessor: "objsubid",
+    //   Header: gettext("objsubid?"),
+    //   sortble: true,
+    //   resizable: false,
+    //   disableGlobalFilter: false,
+    // },
+  ];
+
+  const databasePreparedColumns = [
+    {
+      accessor: 'git',
+      Header: gettext('Name'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'Owner',
+      Header: gettext('Owner'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'transaction',
+      Header: gettext('XID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'prepared',
+      Header: gettext('Prepared at'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+
+
+  const canTakeAction = (row, cellAction, itemNodeData, treeNodeInfo) => {
+    // We will validate if user is allowed to cancel the active query
+    // If there is only one active session means it probably our main
+    // connection session
+    // console.log(row, '===>', nodeData, treeNodeInfo, node.collection);
+    // // m.collection.where({
+    // //   'state': 'active',
+    // // }),
+    cellAction = cellAction || null;
+    var pg_version = treeNodeInfo.server.version || null,
+      is_cancel_session = cellAction === 'cancel',
+      txtMessage,
+      maintenance_database = treeNodeInfo.server.db,
+      is_super_user,
+      current_user;
+
+    var can_signal_backend =
+      treeNodeInfo.server && treeNodeInfo.server.user
+        ? treeNodeInfo.server.user.can_signal_backend
+        : false;
+
+    if (
+      treeNodeInfo.server &&
+      treeNodeInfo.server.user &&
+      treeNodeInfo.server.user.is_superuser
+    ) {
+      is_super_user = true;
+    } else {
+      is_super_user = false;
+      current_user =
+        treeNodeInfo.server && treeNodeInfo.server.user
+          ? treeNodeInfo.server.user.name
+          : null;
+    }
+
+    // With PG10, We have background process showing on dashboard
+    // We will not allow user to cancel them as they will fail with error
+    // anyway, so better usability we will throw our on notification
+
+    // Background processes do not have database field populated
+    if (pg_version && pg_version >= 100000 && !row.original.datname) {
+      if (is_cancel_session) {
+        txtMessage = gettext('You cannot cancel background worker processes.');
+      } else {
+        txtMessage = gettext(
+          'You cannot terminate background worker processes.'
+        );
+      }
+      Notify.info(txtMessage);
+      return false;
+      // If it is the last active connection on maintenance db then error out
+    } else if (
+      maintenance_database == row.original.datname &&
+      row.original.state == 'active'
+    ) {
+      if (is_cancel_session) {
+        txtMessage = gettext(
+          'You are not allowed to cancel the main active session.'
+        );
+      } else {
+        txtMessage = gettext(
+          'You are not allowed to terminate the main active session.'
+        );
+      }
+      Notify.error(txtMessage);
+      return false;
+    } else if (is_cancel_session && row.original.state == 'idle') {
+      // If this session is already idle then do nothing
+      Notify.info(gettext('The session is already in idle state.'));
+      return false;
+    } else if (can_signal_backend) {
+      // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
+      return true;
+    } else if (is_super_user) {
+      // Super user can do anything
+      return true;
+    } else if (current_user && current_user == treeNodeInfo.server.user) {
+      // Non-super user can cancel only their active queries
+      return true;
+    } else {
+      // Do not allow to cancel someone else session to non-super user
+      if (is_cancel_session) {
+        txtMessage = gettext(
+          'Superuser privileges are required to cancel another users query.'
+        );
+      } else {
+        txtMessage = gettext(
+          'Superuser privileges are required to terminate another users query.'
+        );
+      }
+      Notify.error(txtMessage);
+      return false;
+    }
+  };
+
+  useEffect(() => {
+    let url,
+      message = gettext(
+        'Please connect to the selected server to view the dashboard.'
+      );
+
+    if (sid && props.serverConnected) {
+      if (val === 0) {
+        url = url_for('dashboard.activity');
+      } else if (val === 1) {
+        url = url_for('dashboard.locks');
+      } else if (val === 2) {
+        url = url_for('dashboard.prepared');
+      } else {
+        url = url_for('dashboard.config');
+      }
+
+      message = gettext('Loading dashboard...');
+      if (did) url += sid + '/' + did;
+      else url += sid;
+
+      const api = getApiInstance();
+      if (node) {
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            setdashData(parseData(res.data));
+          })
+          .catch((e) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(e.message)
+            );
+            // show failed message.
+            setMsg(gettext('Failed to retrieve data from the server.'));
+          });
+      } else {
+        setMsg(message);
+      }
+    }
+    if (message != '') {
+      setMsg(message);
+    }
+  }, [nodeData, val, did]);
+
+
+  return (
+    <>
+      {sid && props.serverConnected ? (
+        <Box className={classes.emptyPanel}>
+          <Graphs
+            preferences={preferences}
+            sid={sid}
+            did={did && did}
+            pageVisible={true}
+          ></Graphs>
+          <Box className={classes.panelContent}>
+            <Box className={classes.cardHeader} title={gettext('Server activity')}>
+              {gettext('Server activity')}{' '}
+            </Box>
+            {/* <Box className={classes.panelContent}> */}
+            <Tabs
+              value={val}
+              onChange={tabChanged}
+              className={classes.searchInput}
+            >
+              {tab.map((tabValue, i) => {
+                return <Tab key={i} label={tabValue} />;
+              })}
+            </Tabs>
+            {/* </Box> */}
+            {/* <Box className={classes.component}> */}
+            <PgTable
+              // className={classes.autoResizer}searchText={searchVal}
+              // type={"panel"}
+              // className={classes.autoResizer}
+              className={classes.table}
+              columns={
+                val === 0
+                  ? activityColumns
+                  : val === 1
+                    ? databaseLocksColumns
+                    : val == 2
+                      ? databasePreparedColumns
+                      : serverConfigColumns
+              }
+              data={dashData}
+              schema={schema}
+            ></PgTable>
+            {/* </Box> */}
+          </Box>
+        </Box>
+      ) : sid && !props.serverConnected ? (
+        <div className={classes.emptyPanel}>
+          <div className={classes.panelIcon}>
+            <i className="fa fa-exclamation-circle"></i>
+            <span className={classes.panelMessage}>{gettext(msg)}</span>
+          </div>
+        </div>
+      ) : (
+        <WelcomeDashboard
+          pgBrowser={pgBrowser}
+          node={node}
+          itemData={nodeData}
+          item={item}
+          sid={sid}
+          did={did}
+        />
+      )}
+    </>
+  );
+}
+
+Dashboard.propTypes = {
+  node: PropTypes.func,
+  itemData: PropTypes.object,
+  nodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  item: PropTypes.object,
+  pgBrowser: PropTypes.object,
+  preferences: PropTypes.object,
+  sid: PropTypes.string,
+  did: PropTypes.oneOfType([
+    PropTypes.bool,
+    PropTypes.number
+  ]),
+  row: PropTypes.object,
+  serverConnected: PropTypes.bool,
+};
+
+
+export function ChartContainer(props) {
+  return (
+    <div className="card dashboard-graph" role="object-document" tabIndex="0" aria-labelledby={props.id}>
+      <div className="card-header">
+        <div className="d-flex">
+          <div id={props.id}>{props.title}</div>
+          <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
+        </div>
+      </div>
+      <div className="card-body dashboard-graph-body">
+        <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none' : '')}>
+          {props.children}
+        </div>
+        <ChartError message={props.errorMsg} />
+      </div>
+    </div>
+  );
+}
+
+ChartContainer.propTypes = {
+  id: PropTypes.string.isRequired,
+  title: PropTypes.string.isRequired,
+  legendRef: PropTypes.oneOfType([
+    PropTypes.func,
+    PropTypes.shape({ current: PropTypes.any }),
+  ]).isRequired,
+  children: PropTypes.node.isRequired,
+  errorMsg: PropTypes.string,
+};
+
+export function ChartError(props) {
+  if (props.message === null) {
+    return <></>;
+  }
+  return (
+    <div className="pg-panel-error pg-panel-message" role="alert">{props.message}</div>
+  );
+}
+
+ChartError.propTypes = {
+  message: PropTypes.string,
+};
+
+export function DashboardRow({ children }) {
+  return (
+    <div className="row dashboard-row">{children}</div>
+  );
+}
+DashboardRow.propTypes = {
+  children: PropTypes.node.isRequired,
+};
+
+export function DashboardRowCol({ breakpoint, parts, children }) {
+  return (
+    <div className={`col-${breakpoint}-${parts}`}>{children}</div>
+  );
+}
+
+DashboardRowCol.propTypes = {
+  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
+  parts: PropTypes.number.isRequired,
+  children: PropTypes.node.isRequired,
+};
diff --git a/web/pgadmin/dashboard/static/js/Graphs.jsx b/web/pgadmin/dashboard/static/js/Graphs.jsx
index cd8fa65a3..69a9af4fc 100644
--- a/web/pgadmin/dashboard/static/js/Graphs.jsx
+++ b/web/pgadmin/dashboard/static/js/Graphs.jsx
@@ -8,7 +8,7 @@
 //////////////////////////////////////////////////////////////
 import React, { useEffect, useRef, useState, useReducer, useCallback, useMemo } from 'react';
 import {LineChart} from 'sources/chartjs';
-import {ChartContainer, DashboardRowCol, DashboardRow} from './dashboard_components';
+import {ChartContainer, DashboardRowCol, DashboardRow} from './Dashboard';
 import url_for from 'sources/url_for';
 import axios from 'axios';
 import gettext from 'sources/gettext';
diff --git a/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
new file mode 100644
index 000000000..265e01d2e
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
@@ -0,0 +1,418 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import gettext from 'sources/gettext';
+import _ from 'lodash';
+import { Link, BrowserRouter } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import { makeStyles } from '@material-ui/core/styles';
+import pgAdmin from 'sources/pgadmin';
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    background: theme.palette.grey[400],
+    overflow: 'hidden',
+    padding: '8px',
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+    height: '100%'
+
+  },
+  dashboardContainer: {
+    paddingTop: '7.5px',
+    paddingBottom: '7.5px',
+    minHeight: '100%'
+  },
+  card: {
+    position: 'relative',
+    minWidth: 0,
+    wordWrap: 'break-word',
+    backgroundColor: '#fff',
+    backgroundClip: 'border-box',
+    border: '1px solid #dde0e6',
+    borderRadius: '0.25rem'
+  },
+  row: {
+    marginRight: '-7.5px',
+    marginLeft: '-7.5px'
+  },
+  cardHeader: {
+    padding: '0.25rem 0.5rem',
+    fontWeight: 'bold',
+    backgroundColor: '#fff',
+    color: '#222222',
+    borderColor: '#dde0e6'
+  }
+
+}));
+
+
+function AddNewServer(pgBrowser) {
+  if (pgBrowser && pgBrowser.tree) {
+    var i = _.isUndefined(pgBrowser.tree.selected()) ?
+        pgBrowser.tree.first(null, false) :
+        pgBrowser.tree.selected(),
+      serverModule = pgAdmin.Browser.Nodes.server,
+      itemData = pgBrowser.tree.itemData(i);
+
+    while (itemData && itemData._type != 'server_group') {
+      i = pgBrowser.tree.next(i);
+      itemData = pgBrowser.tree.itemData(i);
+    }
+
+    if (!itemData) {
+      return;
+    }
+
+    if (serverModule) {
+      serverModule.callbacks.show_obj_properties.apply(
+        serverModule, [{
+          action: 'create',
+        }, i]
+      );
+    }
+  }
+}
+
+export default function WelcomeDashboard({ pgBrowser }) {
+
+  const classes = useStyles();
+
+  return (
+    <BrowserRouter>
+      <div className={classes.emptyPanel}>
+        <div className={classes.dashboardContainer}>
+          <div className={classes.row}>
+            <div className="col-12">
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Welcome')}</div>
+                <div className="card-body p-2">
+                  <div className="welcome-logo" aria-hidden="true">
+                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 130">
+                      <defs>
+                        <style>{'.cls-1{stroke:#000;stroke-width:10.19px;}.cls-2{fill:#336791;}.cls-3,.cls-4,.cls-9{fill:none;}.cls-3,.cls-4,.cls-5,.cls-6{stroke:#fff;}.cls-3,.cls-4{stroke-linecap:round;stroke-width:3.4px;}.cls-3{stroke-linejoin:round;}.cls-4{stroke-linejoin:bevel;}.cls-5,.cls-6{fill:#fff;}.cls-5{stroke-width:1.13px;}.cls-6{stroke-width:0.57px;}.cls-7{fill:#2775b6;}.cls-8{fill:#333;}.cls-9{stroke:#333;stroke-width:3px;}'}</style>
+                      </defs>
+                      <title>pgAdmin_PostgreSQL</title>
+                      <g id="Layer_1" data-name="Layer 1">
+                        <g id="Layer_3">
+                          <path
+                            className="cls-1"
+                            d="M95.59,93.65c.77-6.44.54-7.38,5.33-6.34l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21a9,9,0,0,0,.1,2.46c-3.7,4.13-2.62,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.46,1.16,1.36,8.35,1.56,13.48s.55,9.93,1.6,12.75,2.28,10.1,12,8C88.81,119.46,95,117,95.59,93.65"
+                          />
+                          <path
+                            className="cls-2"
+                            d="M117.17,79.2c-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21A9.41,9.41,0,0,0,59,80.22c-3.7,4.13-2.61,4.86-10,6.38s-3.08,4.29-.21,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.45,1.16,2.47,7.56,2.3,13.35s-.28,9.77.86,12.88,2.28,10.1,12,8C88.81,119.46,93,115,93.6,107.42,94,102.07,95,102.87,95,98.08l.75-2.26c.87-7.26.14-9.6,5.15-8.51l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31Z"
+                          />
+                          <path
+                            className="cls-3"
+                            d="M66.33,83.36c-.38,13.5.09,27.09,1.41,30.39s4.15,9.73,13.88,7.64c8.12-1.74,11.08-5.11,12.36-12.55.94-5.47,2.77-20.67,3-23.79"
+                          />
+                          <path
+                            className="cls-3"
+                            d="M54.67,15.7s-44-18-42,22.93c.44,8.7,12.48,65.87,26.84,48.6,5.25-6.32,10-11.27,10-11.27"
+                          />
+                          <path
+                            className="cls-3"
+                            d="M78.45,12.42c-1.52.47,24.49-9.51,39.28,9.38,5.22,6.67-.83,33.94-15.31,55.42"
+                          />
+                          <path
+                            className="cls-4"
+                            d="M102.42,77.22s.94,4.64,14.65,1.81c6-1.24,2.4,3.48-3.7,6.31-5,2.32-16.21,2.92-16.39-.29-.47-8.27,5.9-5.76,5.44-7.83-.42-1.87-3.26-3.7-5.15-8.27-1.64-4-22.57-34.58,5.8-30,1-.22-7.4-27-33.95-27.42S43.45,44.14,43.45,44.14"
+                          />
+                          <path
+                            className="cls-3"
+                            d="M58.9,80.05c-3.7,4.13-2.61,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52,1.66-2.32,0-6-2.28-7-1.1-.46-2.57-1-4.46,1.09Z"
+                          />
+                          <path
+                            className="cls-3"
+                            d="M58.66,80c-.38-2.44.79-5.33,2.05-8.71C62.6,66.19,67,61.11,63.47,45c-2.6-12-20-2.5-20-.87a81.48,81.48,0,0,1-.29,16c-1.41,10.06,6.4,18.57,15.39,17.7"
+                          />
+                          <path
+                            className="cls-5"
+                            d="M54.51,43.9c-.08.55,1,2,2.45,2.23a2.62,2.62,0,0,0,2.72-1.51c.08-.56-1-1.17-2.44-1.37s-2.65.09-2.73.65Z"
+                          />
+                          <path
+                            className="cls-6"
+                            d="M98,42.76c.07.56-1,2-2.45,2.24a2.64,2.64,0,0,1-2.73-1.52c-.07-.55,1-1.16,2.45-1.36s2.65.09,2.73.64Z"
+                          />
+                          <path
+                            className="cls-3"
+                            d="M103.07,38.92c.24,4.36-.94,7.33-1.08,12-.22,6.74,3.21,14.46-2,22.19"
+                          />
+                        </g>
+                        <path
+                          className="cls-7 app-name"
+                          d="M154.72,28.15h5.16v4.16A12.84,12.84,0,0,1,163.35,29a11.17,11.17,0,0,1,6.28-1.76,11.84,11.84,0,0,1,9.08,4.09c2.48,2.72,3.73,6.62,3.73,11.67q0,10.26-5.38,14.65a12.2,12.2,0,0,1-7.95,2.79,10.78,10.78,0,0,1-6-1.56,13.55,13.55,0,0,1-3.14-3v16h-5.28Zm19.84,24.6Q177,49.65,177,43.5a17,17,0,0,0-1.09-6.44,7.51,7.51,0,0,0-7.53-5.19q-5.49,0-7.52,5.48a21.49,21.49,0,0,0-1.09,7.44A15.64,15.64,0,0,0,160.88,51a8,8,0,0,0,13.68,1.78Z"
+                        />
+                        <path
+                          className="cls-7 app-name"
+                          d="M206,29.26a14.6,14.6,0,0,1,3,3V28.3h4.86V56.83c0,4-.58,7.13-1.75,9.44q-3.27,6.38-12.35,6.38a15.07,15.07,0,0,1-8.5-2.27,8.86,8.86,0,0,1-3.85-7.1h5.36a6,6,0,0,0,1.52,3.25q1.77,1.75,5.59,1.76,6,0,7.9-4.28,1.1-2.52,1-9a10.39,10.39,0,0,1-3.8,3.57,13.56,13.56,0,0,1-14.75-2.45q-3.81-3.62-3.81-12,0-7.89,3.84-12.31a11.85,11.85,0,0,1,9.27-4.42A11.37,11.37,0,0,1,206,29.26Zm.64,5.66a7.61,7.61,0,0,0-6.09-2.81A7.52,7.52,0,0,0,193,37.32a20.56,20.56,0,0,0-1.08,7.3c0,3.53.72,6.22,2.14,8.07a6.93,6.93,0,0,0,5.76,2.77,8.09,8.09,0,0,0,8-5.13A16.72,16.72,0,0,0,209,43.56Q209,37.73,206.62,34.92Z"
+                        />
+                        <path
+                          className="cls-7 app-name"
+                          d="M235.16,16.34h6.58l15.62,43H251l-4.5-12.89H229.6l-4.67,12.89h-6Zm9.67,25.4-6.63-19-6.88,19Z"
+                        />
+                        <path
+                          className="cls-7 app-name"
+                          d="M279.16,29a14.3,14.3,0,0,1,3.18,3.08V16.2h5.07V59.38h-4.75V55a11.33,11.33,0,0,1-4.35,4.19,12.51,12.51,0,0,1-5.75,1.28,11.61,11.61,0,0,1-9-4.4q-3.82-4.41-3.83-11.74a20.35,20.35,0,0,1,3.49-11.88,11.41,11.41,0,0,1,10-5A11.15,11.15,0,0,1,279.16,29ZM267.39,52.5q2.13,3.39,6.82,3.39a7.17,7.17,0,0,0,6-3.14c1.56-2.1,2.35-5.12,2.35-9s-.81-6.9-2.42-8.81a7.56,7.56,0,0,0-6-2.85,7.88,7.88,0,0,0-6.43,3c-1.64,2-2.46,5-2.46,9A15.62,15.62,0,0,0,267.39,52.5Z"
+                        />
+                        <path
+                          className="cls-7 app-name"
+                          d="M295.29,28h5.21v4.46a17.4,17.4,0,0,1,3.4-3.37,10.24,10.24,0,0,1,5.92-1.79,9.34,9.34,0,0,1,6,1.85,9.61,9.61,0,0,1,2.34,3.1,11.37,11.37,0,0,1,4.13-3.73,11.52,11.52,0,0,1,5.33-1.22q6.33,0,8.62,4.57a15,15,0,0,1,1.23,6.62V59.38H332V37.58c0-2.09-.52-3.52-1.57-4.3a6.2,6.2,0,0,0-3.82-1.17,7.58,7.58,0,0,0-5.35,2.08c-1.49,1.38-2.24,3.7-2.24,6.94V59.38h-5.36V38.9a10.78,10.78,0,0,0-.76-4.66q-1.2-2.19-4.49-2.19A7.73,7.73,0,0,0,303,34.36c-1.63,1.54-2.45,4.34-2.45,8.38V59.38h-5.27Z"
+                        />
+                        <path
+                          className="cls-7 app-name"
+                          d="M345.27,16.34h5.36v6h-5.36Zm0,11.81h5.36V59.38h-5.36Z"
+                        />
+                        <path
+                          className="cls-7 app-name"
+                          d="M358.6,28h5v4.46a14,14,0,0,1,4.72-4,12.56,12.56,0,0,1,5.53-1.2c4.46,0,7.46,1.55,9,4.66a16.52,16.52,0,0,1,1.29,7.29V59.38h-5.37V39.61A10.8,10.8,0,0,0,378,35a5.15,5.15,0,0,0-5.1-2.93,10.21,10.21,0,0,0-3.08.38A8,8,0,0,0,366,35a7.66,7.66,0,0,0-1.71,3.2,21.84,21.84,0,0,0-.4,4.74V59.38H358.6Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M155.24,86.87h3.9l5.77,17,5.74-17h3.87V107h-2.6V95.1q0-.61,0-2c0-.94,0-2,0-3L166.24,107h-2.7L157.75,90v.61c0,.49,0,1.24,0,2.25s.05,1.75.05,2.22V107h-2.6Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M186.15,98.09a1.35,1.35,0,0,0,1.14-.71,2.31,2.31,0,0,0,.16-.94,2,2,0,0,0-.89-1.84A4.79,4.79,0,0,0,184,94a3.21,3.21,0,0,0-2.73,1,3.44,3.44,0,0,0-.59,1.72h-2.3A4.28,4.28,0,0,1,180.14,93,7.16,7.16,0,0,1,184.05,92a8,8,0,0,1,4.19,1,3.34,3.34,0,0,1,1.6,3.06v8.44a1.06,1.06,0,0,0,.16.62.77.77,0,0,0,.66.23l.37,0,.44-.07V107a7.38,7.38,0,0,1-.88.21,5.92,5.92,0,0,1-.82,0,2,2,0,0,1-1.84-.9,3.63,3.63,0,0,1-.43-1.36,6.16,6.16,0,0,1-2.16,1.71,6.56,6.56,0,0,1-3.1.73,4.59,4.59,0,0,1-3.33-1.24,4.09,4.09,0,0,1-1.29-3.09,4,4,0,0,1,1.27-3.16,6.16,6.16,0,0,1,3.34-1.38ZM181,104.74a2.88,2.88,0,0,0,1.84.62,5.51,5.51,0,0,0,2.52-.61,3.37,3.37,0,0,0,2-3.26v-2a3.79,3.79,0,0,1-1.16.48,10.37,10.37,0,0,1-1.39.28l-1.49.19a5.68,5.68,0,0,0-2,.56,2.18,2.18,0,0,0-1.14,2A2,2,0,0,0,181,104.74Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M193.88,92.31h2.33v2.08a6.73,6.73,0,0,1,2.2-1.85A6,6,0,0,1,201,92q3.12,0,4.21,2.18a7.73,7.73,0,0,1,.6,3.4V107h-2.5V97.73a4.87,4.87,0,0,0-.4-2.16,2.41,2.41,0,0,0-2.38-1.37,4.75,4.75,0,0,0-1.43.18,3.68,3.68,0,0,0-1.78,1.2,3.55,3.55,0,0,0-.8,1.5,10.3,10.3,0,0,0-.18,2.21V107h-2.46Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M217.29,98.09a1.33,1.33,0,0,0,1.14-.71,2.15,2.15,0,0,0,.16-.94,2,2,0,0,0-.89-1.84,4.79,4.79,0,0,0-2.56-.56,3.24,3.24,0,0,0-2.73,1,3.44,3.44,0,0,0-.58,1.72h-2.3A4.27,4.27,0,0,1,211.28,93,7.19,7.19,0,0,1,215.2,92a8,8,0,0,1,4.19,1A3.36,3.36,0,0,1,221,96v8.44a1.14,1.14,0,0,0,.15.62.79.79,0,0,0,.67.23l.37,0,.43-.07V107a7.32,7.32,0,0,1-.87.21,6,6,0,0,1-.82,0,2,2,0,0,1-1.85-.9,3.46,3.46,0,0,1-.42-1.36,6.16,6.16,0,0,1-2.16,1.71,6.63,6.63,0,0,1-3.11.73,4.58,4.58,0,0,1-3.32-1.24,4.06,4.06,0,0,1-1.3-3.09A4,4,0,0,1,210,100a6.13,6.13,0,0,1,3.33-1.38Zm-5.18,6.65a2.91,2.91,0,0,0,1.85.62,5.47,5.47,0,0,0,2.51-.61,3.38,3.38,0,0,0,2.06-3.26v-2a3.9,3.9,0,0,1-1.16.48,10.51,10.51,0,0,1-1.4.28l-1.48.19a5.55,5.55,0,0,0-2,.56,2.17,2.17,0,0,0-1.15,2A2,2,0,0,0,212.11,104.74Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M233.16,92.9a7.05,7.05,0,0,1,1.42,1.39V92.45h2.27v13.32a10,10,0,0,1-.82,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.15,4.15,0,0,1-1.8-3.32H227a2.81,2.81,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.88,0,3.1-.66,3.68-2a11.15,11.15,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,5.93,5.93,0,0,1-2.74.54,5.79,5.79,0,0,1-4.14-1.69q-1.79-1.68-1.78-5.58a8.49,8.49,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.33,5.33,0,0,1,233.16,92.9Zm.3,2.64a3.77,3.77,0,0,0-6.38,1.12,9.73,9.73,0,0,0-.5,3.4,6.05,6.05,0,0,0,1,3.77,3.21,3.21,0,0,0,2.68,1.29,3.77,3.77,0,0,0,3.72-2.39,7.71,7.71,0,0,0,.6-3.16A6.13,6.13,0,0,0,233.46,95.54Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M249.64,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,17.44,17.44,0,0,1,.22,3.23H242.4a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3.05-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.58,6.58,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.71,8.71,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,249.64,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M256.16,92.31h2.44v2.08a8.23,8.23,0,0,1,1.58-1.57A4.79,4.79,0,0,1,263,92a4.31,4.31,0,0,1,2.81.87,4.5,4.5,0,0,1,1.1,1.44,5.27,5.27,0,0,1,1.92-1.74,5.37,5.37,0,0,1,2.49-.57,4.08,4.08,0,0,1,4,2.14,7,7,0,0,1,.58,3.09V107h-2.56V96.78a2.41,2.41,0,0,0-.73-2,2.93,2.93,0,0,0-1.79-.54,3.53,3.53,0,0,0-2.49,1,4.23,4.23,0,0,0-1.05,3.24V107h-2.5V97.4a5,5,0,0,0-.36-2.18,2.17,2.17,0,0,0-2.09-1,3.59,3.59,0,0,0-2.53,1.08c-.76.72-1.14,2-1.14,3.91V107h-2.47Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M288.53,92.72a5.47,5.47,0,0,1,2.22,1.89,6.67,6.67,0,0,1,1,2.58,17.66,17.66,0,0,1,.21,3.23H281.29a6.42,6.42,0,0,0,1,3.59,3.48,3.48,0,0,0,3,1.35,3.9,3.9,0,0,0,3.06-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5.23,5.23,0,0,1-.64,1.8,6.56,6.56,0,0,1-1.2,1.62,5.7,5.7,0,0,1-2.76,1.48,8.62,8.62,0,0,1-2,.21,6.14,6.14,0,0,1-4.61-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.91-5.72,6.24,6.24,0,0,1,5-2.21A6.58,6.58,0,0,1,288.53,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.53,3.53,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.63,4.63,0,0,0-1.2,3.11Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M295.06,92.31h2.34v2.08a6.63,6.63,0,0,1,2.2-1.85,5.91,5.91,0,0,1,2.58-.56c2.08,0,3.49.73,4.21,2.18a7.57,7.57,0,0,1,.61,3.4V107h-2.51V97.73a5,5,0,0,0-.39-2.16,2.41,2.41,0,0,0-2.38-1.37,4.86,4.86,0,0,0-1.44.18,3.7,3.7,0,0,0-1.77,1.2,3.55,3.55,0,0,0-.8,1.5,9.58,9.58,0,0,0-.19,2.21V107h-2.46Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M311.13,88.22h2.48v4.09H316v2h-2.34v9.56a1,1,0,0,0,.52,1,2.21,2.21,0,0,0,1,.15h.38l.48,0v2a4.16,4.16,0,0,1-.88.18,7.74,7.74,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88,3.94,3.94,0,0,1-.61-2.29v-9.7h-2v-2h2Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M340.63,86.87v2.39h-6.77V107h-2.75V89.26h-6.76V86.87Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M350.31,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2A8.08,8.08,0,0,1,338.7,100a8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.6,6.6,0,0,1,350.31,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.49,3.49,0,0,0-3.25,1.72,8.07,8.07,0,0,0-1,4.15,7.05,7.05,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.35,3.35,0,0,0,348.78,103.51Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M365.88,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2,8.08,8.08,0,0,1-1.77-5.48,8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,365.88,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.46,3.46,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.54,3.54,0,0,0,3.21,1.56A3.35,3.35,0,0,0,364.35,103.51Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M370.91,86.87h2.46V107h-2.46Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M378.53,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.86,4.86,0,0,0,2.45-.6A2,2,0,0,0,386,103a1.56,1.56,0,0,0-.84-1.43,10.63,10.63,0,0,0-2.14-.7l-2-.49a10,10,0,0,1-2.81-1,3.11,3.11,0,0,1-1.61-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.83,1.94a4.24,4.24,0,0,1,.91,2.65h-2.33A2.72,2.72,0,0,0,385,95a3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.65,1.65,0,0,0-.74,1.4,1.73,1.73,0,0,0,1,1.53,5.69,5.69,0,0,0,1.64.6l1.66.4A12.73,12.73,0,0,1,387,99.75a3.3,3.3,0,0,1,1.44,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43c-2.2,0-3.77-.5-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M400,87.84c.58-.84,1.68-1.26,3.32-1.26l.48,0,.56,0v2.24l-.56,0h-.32c-.76,0-1.21.19-1.36.58a11.75,11.75,0,0,0-.22,3h2.46v1.94h-2.46V107h-2.43V94.32h-2V92.38h2v-2.3A4.43,4.43,0,0,1,400,87.84Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M417.23,93.77a7.38,7.38,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.18,6.18,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2,8.07,8.07,0,0,1-1.76-5.48,8.83,8.83,0,0,1,1.85-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,417.23,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.47,3.47,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.55,3.55,0,0,0,3.22,1.56A3.35,3.35,0,0,0,415.7,103.51Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M422.26,92.31h2.34v2.53A5.61,5.61,0,0,1,426,93,3.68,3.68,0,0,1,428.59,92l.24,0,.56,0v2.6a2.08,2.08,0,0,0-.41-.05l-.4,0a3.52,3.52,0,0,0-2.86,1.2,4.2,4.2,0,0,0-1,2.75V107h-2.46Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M439.89,86.87h9a6.09,6.09,0,0,1,4.31,1.51,5.5,5.5,0,0,1,1.64,4.25,6.15,6.15,0,0,1-1.47,4.09,5.5,5.5,0,0,1-4.47,1.74h-6.27V107h-2.72Zm10.55,2.76a5.92,5.92,0,0,0-2.46-.42h-5.37v7H448a5.07,5.07,0,0,0,2.95-.78,3.1,3.1,0,0,0,1.14-2.75A3,3,0,0,0,450.44,89.63Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M468.58,93.77a7.38,7.38,0,0,1,1.95,5.55,9.51,9.51,0,0,1-1.72,5.85,6.17,6.17,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2A8.07,8.07,0,0,1,457,100a8.78,8.78,0,0,1,1.86-5.88,6.23,6.23,0,0,1,5-2.18A6.56,6.56,0,0,1,468.58,93.77Zm-1.52,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.65,3.65,0,0,0-3.55-2,3.48,3.48,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.36,3.36,0,0,0,467.06,103.51Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M475,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.93,4.93,0,0,0,2.46-.6,2,2,0,0,0,1.06-1.84,1.55,1.55,0,0,0-.85-1.43,10.4,10.4,0,0,0-2.14-.7l-2-.49a9.78,9.78,0,0,1-2.8-1,3.1,3.1,0,0,1-1.62-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.84,1.94a4.17,4.17,0,0,1,.9,2.65h-2.33a2.72,2.72,0,0,0-.6-1.51,3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.64,1.64,0,0,0-.73,1.4,1.72,1.72,0,0,0,1,1.53,5.66,5.66,0,0,0,1.65.6l1.65.4a12.83,12.83,0,0,1,3.63,1.24,3.31,3.31,0,0,1,1.43,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43q-3.3,0-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M488,88.22h2.49v4.09h2.34v2h-2.34v9.56a1,1,0,0,0,.52,1,2.19,2.19,0,0,0,.95.15h.39l.48,0v2a4.39,4.39,0,0,1-.89.18,7.52,7.52,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88A3.94,3.94,0,0,1,488,104v-9.7h-2v-2h2Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M503.47,92.9a6.78,6.78,0,0,1,1.41,1.39V92.45h2.27v13.32a10,10,0,0,1-.81,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.1,4.1,0,0,1-1.8-3.32h2.5a2.74,2.74,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.87,0,3.1-.66,3.68-2a11.37,11.37,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,6,6,0,0,1-2.74.54,5.83,5.83,0,0,1-4.15-1.69q-1.77-1.68-1.77-5.58a8.43,8.43,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.38,5.38,0,0,1,503.47,92.9Zm.3,2.64a3.56,3.56,0,0,0-2.85-1.31,3.5,3.5,0,0,0-3.53,2.43,9.48,9.48,0,0,0-.51,3.4,6.12,6.12,0,0,0,1,3.77,3.24,3.24,0,0,0,2.69,1.29,3.75,3.75,0,0,0,3.71-2.39,7.71,7.71,0,0,0,.6-3.16A6.14,6.14,0,0,0,503.77,95.54Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M511,92.31h2.33v2.53a5.91,5.91,0,0,1,1.41-1.8A3.69,3.69,0,0,1,517.3,92l.23,0,.56,0v2.6a2.08,2.08,0,0,0-.4-.05l-.41,0a3.48,3.48,0,0,0-2.85,1.2,4.14,4.14,0,0,0-1,2.75V107H511Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M529.27,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,16.6,16.6,0,0,1,.22,3.23H522a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3-1.28,4.37,4.37,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.34,6.34,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.65,8.65,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,529.27,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M537.9,100.47a5.6,5.6,0,0,0,.78,2.78q1.3,2,4.59,2a7.9,7.9,0,0,0,2.69-.44,3.09,3.09,0,0,0,2.34-3,2.64,2.64,0,0,0-1-2.33,9.55,9.55,0,0,0-3.15-1.19l-2.64-.62a11.41,11.41,0,0,1-3.65-1.33A4.23,4.23,0,0,1,536,92.54a5.86,5.86,0,0,1,1.83-4.44A7.16,7.16,0,0,1,543,86.37a8.75,8.75,0,0,1,5.22,1.52,5.57,5.57,0,0,1,2.15,4.87h-2.56a5.12,5.12,0,0,0-.84-2.47c-.79-1.05-2.14-1.57-4.05-1.57a4.51,4.51,0,0,0-3.31,1,3.2,3.2,0,0,0-1,2.35,2.33,2.33,0,0,0,1.19,2.16,16.76,16.76,0,0,0,3.54,1.09l2.73.65a8.15,8.15,0,0,1,3,1.27,4.81,4.81,0,0,1,1.86,4.09,5.14,5.14,0,0,1-2.37,4.77,10.46,10.46,0,0,1-5.5,1.43,8.07,8.07,0,0,1-5.72-1.91,6.57,6.57,0,0,1-2-5.16Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M573.17,106.9l-1.36,1.65-3.11-2.36a11.33,11.33,0,0,1-2.43,1,10.29,10.29,0,0,1-2.85.37,9.18,9.18,0,0,1-7.32-3.06A11.71,11.71,0,0,1,553.76,97a11.9,11.9,0,0,1,2-7,8.78,8.78,0,0,1,7.69-3.72c3.54,0,6.17,1.14,7.87,3.42a11.08,11.08,0,0,1,2,6.82,14.28,14.28,0,0,1-.48,3.73,9.67,9.67,0,0,1-2.44,4.46ZM565.35,105a3.36,3.36,0,0,0,1.29-.47l-2.22-1.72,1.37-1.68,2.62,2A7.5,7.5,0,0,0,570.1,100a13.76,13.76,0,0,0,.45-3.39,8.48,8.48,0,0,0-1.85-5.7,6.35,6.35,0,0,0-5.07-2.17,6.6,6.6,0,0,0-5.15,2.08q-1.9,2.07-1.9,6.38A8.64,8.64,0,0,0,558.4,103a6.63,6.63,0,0,0,5.36,2.15A11.24,11.24,0,0,0,565.35,105Z"
+                        />
+                        <path
+                          className="cls-8 app-tagline"
+                          d="M576.58,86.87h2.72v17.69h10.08V107h-12.8Z"
+                        />
+                        <line
+                          className="cls-9 app-name-underline"
+                          x1="219.17"
+                          y1="66.5"
+                          x2="384.17"
+                          y2="66.5"
+                        />
+                      </g>
+                    </svg>
+                  </div>
+                  <h4>
+                    {gettext('Feature rich')} | {gettext('Maximises PostgreSQL')}{' '}
+                    | {gettext('Open Source')}{' '}
+                  </h4>
+                  <p>
+                    {gettext(
+                      'pgAdmin is an Open Source administration and management tool for the PostgreSQL database. It includes a graphical administration interface, an SQL query tool, a procedural code debugger and much more. The tool is designed to answer the needs of developers, DBAs and system administrators alike.'
+                    )}
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className={classes.row}>
+            <div className="col-12">
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Quick Links')}</div>
+                <div className="card-body p-2">
+                  <div className="row">
+                    <div className="col-6 dashboard-link">
+
+                      <Link to="#" onClick={() => { AddNewServer(pgBrowser); }}>
+                        <span
+                          className="fa fa-4x dashboard-icon fa-server"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Add New Server')}
+                      </Link>
+                    </div>
+                    <div className="col-6 dashboard-link">
+                      {/* <a href="#" onClick={pgAdmin.Preferences.show()}> */}
+                      <a href="#">
+                        <span
+                          id="mnu_preferences"
+                          className="fa fa-4x dashboard-icon fa-cogs"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Configure pgAdmin')}
+                      </a>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className={classes.row}>
+            <div className="col-12">
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Getting Started')}</div>
+                <div className="card-body p-2">
+                  <div className="row">
+                    <div className="col-3 dashboard-link">
+                      <a
+                        href="http://www.postgresql.org/docs"
+                        target="postgres_help"
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon dashboard-pg-doc"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('PostgreSQL Documentation')}
+                      </a>
+                    </div>
+                    <div className="col-3 dashboard-link">
+                      <a href="https://www.pgadmin.org" target="pgadmin_website">
+                        <span
+                          className="fa fa-4x dashboard-icon fa-globe"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('pgAdmin Website')}
+                      </a>
+                    </div>
+                    <div className="col-3 dashboard-link">
+                      <a
+                        href="http://planet.postgresql.org"
+                        target="planet_website"
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon fa-book"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Planet PostgreSQL')}
+                      </a>
+                    </div>
+                    <div className="col-3 dashboard-link">
+                      <a
+                        href="http://www.postgresql.org/community"
+                        target="postgres_website"
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon fa-users"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Community Support')}
+                      </a>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </BrowserRouter>
+  );
+}
+
+
+WelcomeDashboard.propTypes = {
+  pgBrowser: PropTypes.object.isRequired
+};
+
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
deleted file mode 100644
index 258071da4..000000000
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ /dev/null
@@ -1,1209 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import Notify from '../../../static/js/helpers/Notifier';
-
-define('pgadmin.dashboard', [
-  'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
-  'sources/pgadmin', 'backbone', 'backgrid',
-  'pgadmin.alertifyjs', 'pgadmin.backform', 'sources/nodes/dashboard',
-  'sources/window', './ChartsDOM', 'pgadmin.browser', 'bootstrap', 'wcdocker',
-], function(
-  url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid,
-  Alertify, Backform, NodesDashboard, pgWindow, ChartsDOM
-) {
-
-  pgAdmin.Browser = pgAdmin.Browser || {};
-  var pgBrowser = pgAdmin.Browser;
-
-  /* Return back, this has been called more than once */
-  if (pgAdmin.Dashboard)
-    return;
-
-  var dashboardVisible = true,
-    cancel_query_url = '',
-    terminate_session_url = '',
-    is_super_user = false,
-    current_user, maintenance_database,
-    is_server_dashboard = false,
-    is_database_dashboard = false,
-    can_signal_backend = false;
-
-  // Custom BackGrid cell, Responsible for cancelling active sessions
-  var customDashboardActionCell = Backgrid.Extension.DeleteCell.extend({
-    render: function() {
-      this.$el.empty();
-      var self = this,
-        cell_action = self.column.get('cell_action');
-      // if cancel query button then
-      if (cell_action === 'cancel') {
-        this.$el.html(
-          '<i class=\'fa fa-stop\' data-toggle=\'tooltip\' ' +
-          'title=\'' + gettext('Cancel the active query') +
-          '\' aria-label=\''+ gettext('Cancel the active query') +'\'></i>'
-        );
-      } else {
-        this.$el.html(
-          '<i class=\'fa fa-times-circle text-danger\' data-toggle=\'tooltip\' ' +
-          'title=\'' + gettext('Terminate the session') +
-          '\' aria-label=\''+ gettext('Terminate the session') +'\'></i>'
-        );
-      }
-      this.$el.attr('tabindex', 0);
-      this.$el.on('keydown', function(e) {
-        // terminating session or cancel the active query.
-        if (e.keyCode == 32) {
-          self.$el.click();
-        }
-      });
-      this.delegateEvents();
-      return this;
-    },
-    deleteRow: function(e) {
-      var self = this,
-        title, txtConfirm, txtSuccess, txtError, action_url,
-        cell_action = self.column.get('cell_action');
-
-      e.preventDefault();
-
-      var canDeleteRow = Backgrid.callByNeed(
-        self.column.get('canDeleteRow'), self.column, self.model
-      );
-      // If we are not allowed to cancel the query, return from here
-      if (!canDeleteRow)
-        return;
-
-      // This will refresh the grid
-      let refresh_grid = () => {
-        $('#btn_refresh').trigger('click');
-      };
-
-      if (cell_action === 'cancel') {
-        title = gettext('Cancel Active Query?');
-        txtConfirm = gettext('Are you sure you wish to cancel the active query?');
-        txtSuccess = gettext('Active query cancelled successfully.');
-        txtError = gettext('An error occurred whilst cancelling the active query.');
-        action_url = cancel_query_url + self.model.get('pid');
-      } else {
-        title = gettext('Terminate Session?');
-        txtConfirm = gettext('Are you sure you wish to terminate the session?');
-        txtSuccess = gettext('Session terminated successfully.');
-        txtError = gettext('An error occurred whilst terminating the active query.');
-        action_url = terminate_session_url + self.model.get('pid');
-      }
-
-      Notify.confirm(
-        title, txtConfirm,
-        function() {
-          $.ajax({
-            url: action_url,
-            type: 'DELETE',
-          })
-            .done(function(res) {
-              if (res == gettext('Success')) {
-                Notify.success(txtSuccess);
-                refresh_grid();
-              } else {
-                Notify.error(txtError);
-              }
-            })
-            .fail(function(xhr, status, error) {
-              Notify.pgRespErrorNotify(xhr, error);
-            });
-        },
-        function() {
-          return true;
-        }
-      );
-    },
-  });
-
-
-  // Subnode Cell, which will display subnode control
-  var SessionDetailsCell = Backgrid.Extension.ObjectCell.extend({
-    enterEditMode: function() {
-      // Notify that we are about to enter in edit mode for current cell.
-      this.model.trigger('enteringEditMode', [this]);
-
-      Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
-      /* Make sure - we listen to the click event */
-      this.delegateEvents();
-      var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model);
-
-      if (editable) {
-        this.$el.html(
-          '<i class=\'fa fa-caret-down subnode-edit-in-process\'></i>'
-        );
-        this.model.trigger(
-          'pg-sub-node:opened', this.model, this
-        );
-      }
-    },
-    render: function() {
-      this.$el.empty();
-      this.$el.html(
-        '<i class=\'fa fa-caret-right\' data-toggle=\'tooltip\' ' +
-        'title=\'' + gettext('View the active session details') +
-        '\' aria-label=\''+ gettext('View the active session details') +'\'></i>'
-      );
-      this.delegateEvents();
-      if (this.grabFocus)
-        this.$el.trigger('focus');
-      return this;
-    },
-  });
-
-  // Subnode Model
-  var ActiveQueryDetailsModel = Backbone.Model.extend({
-    defaults: {
-      version: null,
-      /* Postgres version */
-    },
-    schema: [{
-      id: 'backend_type',
-      label: gettext('Backend type'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      group: gettext('Details'),
-      visible: function() {
-        return this.version >= 100000;
-      },
-    }, {
-      id: 'query_start',
-      label: gettext('Query started at'),
-      type: 'text',
-      editable: false,
-      readonly: true,
-      group: gettext('Details'),
-    }, {
-      id: 'state_change',
-      label: gettext('Last state changed at'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      group: gettext('Details'),
-    }, {
-      id: 'query',
-      label: gettext('SQL'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      control: Backform.SqlFieldControl,
-      group: gettext('Details'),
-    }],
-  });
-
-  pgAdmin.Dashboard = {
-    init: function() {
-      if (this.initialized)
-        return;
-
-      this.initialized = true;
-      this.chartsDomObj = null;
-
-      this.sid = this.did = -1;
-      this.version = -1;
-
-
-      // Bind the Dashboard object with the 'object_selected' function
-      var selected = this.object_selected.bind(this);
-      var disconnected = this.object_disconnected.bind(this);
-
-      // Listen for selection of any of object
-      pgBrowser.Events.on('pgadmin-browser:tree:selected', selected);
-
-      // Listen for server disconnected event
-      pgBrowser.Events.on('pgadmin:server:disconnect', disconnected);
-
-      // Load the default welcome dashboard
-      var url = url_for('dashboard.index');
-
-      var dashboardPanel = pgBrowser.panels['dashboard'].panel;
-      if (dashboardPanel) {
-        var div = dashboardPanel.layout().scene().find('.pg-panel-content');
-        if (div) {
-          var ajaxHook = function() {
-            $.ajax({
-              url: url,
-              type: 'GET',
-              dataType: 'html',
-            })
-              .done(function(data) {
-                $(div).html(data);
-              })
-              .fail(function(xhr, error) {
-                self.onFail(xhr, error, div, ajaxHook);
-              });
-          };
-          $(div).html(
-            '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
-          );
-          ajaxHook();
-
-          // Cache the current IDs for next time
-          $(dashboardPanel).data('sid', -1);
-          $(dashboardPanel).data('did', -1);
-        }
-      }
-    },
-
-    onFail: function(xhr, error, div, ajaxHook) {
-      Notify.pgNotifier(
-        error, xhr,
-        gettext('An error occurred whilst loading the dashboard.'),
-        function(msg) {
-          if(msg === 'CRYPTKEY_SET') {
-            ajaxHook();
-          } else {
-            $(div).html(
-              '<div class="pg-panel-message" role="alert">' + gettext('An error occurred whilst loading the dashboard.') + '</div>'
-            );
-          }
-        }
-      );
-    },
-
-    // Handle Server Disconnect
-    object_disconnected: function() {
-      let item = pgBrowser.tree.selected(),
-        itemData = item && pgBrowser.tree.itemData(item);
-
-      // The server connected may not be the same one, which was selected, and
-      // we do care out the current selected one only.
-      if (item.length != 0) {
-        this.object_selected(item, itemData);
-      }
-    },
-
-    // Handle treeview clicks
-    object_selected: function(item, itemData) {
-      let self = this;
-
-      if (itemData && itemData._type) {
-        var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
-          url = NodesDashboard.url(itemData, item, treeHierarchy);
-
-        if (url === null) {
-          url = url_for('dashboard.index');
-          self.version = (treeHierarchy.server && treeHierarchy.server.version) || 0;
-
-          cancel_query_url = url + 'cancel_query/';
-          terminate_session_url = url + 'terminate_session/';
-
-          // Check if user is super user
-          var server = treeHierarchy['server'];
-          maintenance_database = (server && server.db) || null;
-          can_signal_backend = (server && server.user) ? server.user.can_signal_backend : false;
-
-          if (server && server.user && server.user.is_superuser) {
-            is_super_user = true;
-          } else {
-            is_super_user = false;
-            // Set current user
-            current_user = (server && server.user) ? server.user.name : null;
-          }
-
-          if ('database' in treeHierarchy) {
-            self.sid = treeHierarchy.server._id;
-            self.did = treeHierarchy.database._id;
-            is_server_dashboard = false;
-            is_database_dashboard = true;
-            url += self.sid + '/' + self.did;
-            cancel_query_url += self.sid + '/' + self.did + '/';
-            terminate_session_url += self.sid + '/' + self.did + '/';
-          } else if ('server' in treeHierarchy) {
-            self.sid = treeHierarchy.server._id;
-            self.did = -1;
-            is_server_dashboard = true;
-            is_database_dashboard = false;
-            url += self.sid;
-            cancel_query_url += self.sid + '/';
-            terminate_session_url += self.sid + '/';
-          } else {
-            is_server_dashboard = is_database_dashboard = false;
-          }
-        } else {
-          is_server_dashboard = is_database_dashboard = false;
-        }
-
-        var dashboardPanel = pgBrowser.panels['dashboard'].panel;
-        if (dashboardPanel) {
-          var div = dashboardPanel.layout().scene().find(
-            '.pg-panel-content'
-          );
-
-          if (div) {
-            if (itemData.connected || _.isUndefined(itemData.connected)) {
-              // Avoid unnecessary reloads
-              if (
-                url !== $(dashboardPanel).data('dashboard_url') || (
-                  url === $(dashboardPanel).data('dashboard_url') &&
-                  $(dashboardPanel).data('server_status') == false
-                )
-              ) {
-                this.chartsDomObj && this.chartsDomObj.unmount();
-                $(div).empty();
-
-                let ajaxHook = function() {
-                  $.ajax({
-                    url: url,
-                    type: 'GET',
-                    dataType: 'html',
-                  })
-                    .done(function(data) {
-                      $(div).html(data);
-                      self.init_dashboard();
-                    })
-                    .fail(function(xhr, error) {
-                      self.onFail(xhr, error, div, ajaxHook);
-                    });
-                };
-                $(div).html(
-                  '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
-                );
-                ajaxHook();
-                $(dashboardPanel).data('server_status', true);
-              }
-            } else {
-              this.chartsDomObj && this.chartsDomObj.unmount();
-              $(div).html(
-                '<div class="pg-panel-message" role="alert">' + gettext('Please connect to the selected server to view the dashboard.') + '</div>'
-              );
-              $(dashboardPanel).data('server_status', false);
-            }
-            // Cache the current IDs for next time
-            $(dashboardPanel).data('dashboard_url', url);
-          }
-        }
-      }
-    },
-
-    // Handler function to support the "Add Server" link
-    add_new_server: function() {
-      if (pgBrowser && pgBrowser.tree) {
-        var i = _.isUndefined(pgBrowser.tree.selected()) ?
-            pgBrowser.tree.first(null, false):
-            pgBrowser.tree.selected(),
-          serverModule = require('pgadmin.node.server'),
-          itemData = pgBrowser.tree.itemData(i);
-
-        while (itemData && itemData._type != 'server_group') {
-          i = pgBrowser.tree.next(i);
-          itemData = pgBrowser.tree.itemData(i);
-        }
-
-        if (!itemData) {
-          return;
-        }
-
-        if (serverModule) {
-          serverModule.callbacks.show_obj_properties.apply(
-            serverModule, [{
-              action: 'create',
-            }, i]
-          );
-        }
-      }
-    },
-
-    // Render a grid
-    render_grid: function(container, url, columns) {
-      var Datum = Backbone.Model.extend({}),
-        self = this;
-
-      var path = url + self.sid;
-      if (self.did != -1) {
-        path += '/' + self.did;
-      }
-
-      var Data = Backbone.Collection.extend({
-        model: Datum,
-        url: path,
-        mode: 'client',
-      });
-
-      var data = new Data();
-
-      var HighlightedRow = Backgrid.Row.extend({
-        render: function() {
-          Backgrid.Row.prototype.render.call(this);
-          var row_type = this.model.get('row_type');
-
-          if (_.isUndefined(row_type) || _.isNull(row_type)) {
-            this.$el.removeClass('alert');
-            this.$el.removeClass('warning');
-          } else if (row_type === 'warning') {
-            this.$el.addClass('warning');
-          } else if (row_type === 'alert') {
-            this.$el.addClass('alert');
-          }
-
-          return this;
-        }
-      });
-
-      // Set up the grid
-      var grid = new Backgrid.Grid({
-        emptyText: gettext('No data found'),
-        columns: columns,
-        collection: data,
-        className: 'backgrid presentation table table-bordered table-noouter-border table-hover',
-        row: HighlightedRow
-      });
-
-      // Render the grid
-      $(container).empty();
-      $(container).append(grid.render().el);
-
-      // Initialize a client-side filter to filter on the client
-      // mode pageable collection's cache.
-      var filter = new Backgrid.Extension.ClientSideFilter({
-        collection: data,
-      });
-
-      filter.setCustomSearchBox($('#txtGridSearch'));
-      // Stash objects for future use
-      $(container).data('data', data);
-      $(container).data('grid', grid);
-      $(container).data('filter', filter);
-    },
-    __loadMoreRows: function(e) {
-      let elem = e.currentTarget;
-      if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
-        if (this.data.length > 0) {
-          this.local_grid.collection.add(this.data.splice(0, 50));
-        }
-      }
-    },
-    // Render the data in a grid
-    render_grid_data: function(container) {
-      var that = this;
-      var data = $(container).data('data'),
-        grid = $(container).data('grid'),
-        filter = $(container).data('filter');
-
-      if (_.isUndefined(data)) {
-        return null;
-      }
-
-      data.fetch({
-        reset: true,
-        success: function(res) {
-          that.data = res.models;
-          that.local_grid = grid;
-          grid.collection.reset(that.data.splice(0,50));
-
-          // If we're showing an error, remove it, and replace the grid & filter
-          if ($(container).hasClass('grid-error')) {
-            $(container).removeClass('grid-error');
-            $(container).html(grid.render().el);
-            $(filter.el).show();
-          }
-
-          if(that.data.length > 50) {
-            // Listen scroll event to load more rows
-            $('.wcScrollableY').on('scroll', that.__loadMoreRows.bind(that));
-          } else {
-            // Listen scroll event to load more rows
-            $('.wcScrollableY').off('scroll', that.__loadMoreRows);
-          }
-
-          // Re-apply search criteria
-          filter.search();
-        },
-        error: function(model, xhr) {
-          let err = '';
-          let msg = '';
-          let cls = 'info';
-
-          if (xhr.readyState === 0) {
-            msg = gettext('Not connected to the server or the connection to the server has been closed.');
-          } else {
-            err = JSON.parse(xhr.responseText);
-            msg = err.errormsg;
-
-            // If we get a 428, it means the server isn't connected
-            if (xhr.status === 428) {
-              if (_.isUndefined(msg) || _.isNull(msg)) {
-                msg = gettext('Please connect to the selected server to view the table.');
-              }
-            } else {
-              msg = gettext('An error occurred whilst rendering the table.');
-              cls = 'error';
-            }
-          }
-
-          // Replace the content with the error, if not already present. Always update the message
-          if (!$(container).hasClass('grid-error')) {
-            $(filter.el).hide();
-            $(container).addClass('grid-error');
-          }
-
-          $(container).html(
-            '<div class="pg-panel-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
-          );
-
-          // Try again
-          setTimeout(function() {
-            pgAdmin.Dashboard.render_grid_data(container, data);
-          }, 5000);
-        },
-      });
-    },
-
-    // Rock n' roll on the dashboard
-    init_dashboard: function() {
-      let self = this;
-
-      this.chartsDomObj = new ChartsDOM.default(
-        document.getElementById('dashboard-graphs'),
-        self.preferences,
-        self.sid,
-        self.did,
-        $('.dashboard-container')[0].clientHeight <=0 ? false : true
-      );
-
-      /* Cache may take time to load for the first time
-       * Keep trying till available
-       */
-      let cacheIntervalId = setInterval(function() {
-        try {
-          if(pgWindow.default.pgAdmin.Browser.preference_version() > 0) {
-            clearInterval(cacheIntervalId);
-            self.reflectPreferences();
-          }
-        }
-        catch(err) {
-          clearInterval(cacheIntervalId);
-          throw err;
-        }
-      },0);
-
-      /* Register for preference changed event broadcasted */
-      pgBrowser.onPreferencesChange('dashboards', function() {
-        self.reflectPreferences();
-      });
-    },
-
-    reflectPreferences: function() {
-      var self = this;
-      self.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('dashboards');
-      this.chartsDomObj.reflectPreferences(self.preferences);
-
-      if(is_server_dashboard || is_database_dashboard) {
-        if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
-          $('#dashboard-activity').removeClass('dashboard-hidden');
-        }
-        else if(!self.preferences.show_activity) {
-          $('#dashboard-activity').addClass('dashboard-hidden');
-        }
-
-        if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
-          $('#dashboard-activity').removeClass('dashboard-hidden');
-        }
-        else if(!self.preferences.show_activity) {
-          $('#dashboard-activity').addClass('dashboard-hidden');
-        }
-
-        /* Dashboard specific preferences can be updated in the
-         * appropriate functions
-         */
-        if(is_server_dashboard) {
-          self.reflectPreferencesServer();
-        }
-        else if(is_database_dashboard) {
-          self.reflectPreferencesDatabase();
-        }
-      }
-    },
-
-    renderTab: function(e, tab_grid_map) {
-      let prevGrid = tab_grid_map[$(e.relatedTarget).attr('aria-controls')];
-      $(prevGrid).data('filtertext', $('#txtGridSearch').val());
-
-      let currGrid = tab_grid_map[$(e.target).attr('aria-controls')];
-      $('#txtGridSearch').val($(currGrid).data('filtertext'));
-      pgAdmin.Dashboard.render_grid_data(currGrid);
-    },
-
-    reflectPreferencesServer: function() {
-      var self = this;
-      var $dashboardContainer = $('.dashboard-container');
-      var div_server_activity = $dashboardContainer.find('#server_activity').get(0);
-      var div_server_locks = $dashboardContainer.find('#server_locks').get(0);
-      var div_server_prepared = $dashboardContainer.find('#server_prepared').get(0);
-      var div_server_config = $dashboardContainer.find('#server_config').get(0);
-
-      var tab_grid_map = {
-        'tab_server_activity': div_server_activity,
-        'tab_server_locks': div_server_locks,
-        'tab_server_prepared': div_server_prepared,
-        'tab_server_config': div_server_config,
-      };
-
-      // Display server activity
-      if (self.preferences.show_activity) {
-        var server_activity_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'datname',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'usename',
-          label: gettext('User'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'application_name',
-          label: gettext('Application'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'client_addr',
-          label: gettext('Client'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'backend_start',
-          label: gettext('Backend start'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'state',
-          label: gettext('State'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        if (self.version < 90600) {
-          server_activity_columns = server_activity_columns.concat(
-            [{
-              name: 'waiting',
-              label: gettext('Waiting?'),
-              editable: false,
-              cell: 'string',
-            }]);
-        } else {
-          server_activity_columns = server_activity_columns.concat(
-            [{
-              name: 'wait_event',
-              label: gettext('Wait event'),
-              editable: false,
-              cell: 'string',
-            }, {
-              name: 'blocking_pids',
-              label: gettext('Blocking PIDs'),
-              editable: false,
-              cell: 'string',
-            }]);
-        }
-
-        var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
-
-        var subNodeFieldsModel = Backform.generateViewSchema(
-          null, newActiveQueryDetailsModel, 'create', null, null, true
-        );
-
-        // Add version to each field
-        _.each(subNodeFieldsModel[0].fields, function(obj) {
-          obj['version'] = self.version;
-        });
-
-        // Add cancel active query button
-        server_activity_columns.unshift({
-          name: 'pg-backform-expand',
-          label: '',
-          cell: SessionDetailsCell,
-          cell_priority: -1,
-          postgres_version: self.version,
-          schema: subNodeFieldsModel,
-        });
-
-        // Add cancel active query button
-        server_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'cancel',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        server_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'terminate',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        var server_locks_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'datname',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'locktype',
-          label: gettext('Lock type'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'relation',
-          label: gettext('Target relation'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'page',
-          label: gettext('Page'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'tuple',
-          label: gettext('Tuple'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualxid',
-          label: gettext('vXID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transactionid',
-          label: gettext('XID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'classid',
-          label: gettext('Class'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'objid',
-          label: gettext('Object ID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualtransaction',
-          label: gettext('vXID (owner)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'mode',
-          label: gettext('Mode'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'granted',
-          label: gettext('Granted?'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var server_prepared_columns = [{
-          name: 'git',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'database',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'Owner',
-          label: gettext('Owner'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transaction',
-          label: gettext('XID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'prepared',
-          label: gettext('Prepared at'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var server_config_columns = [{
-          name: 'name',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'category',
-          label: gettext('Category'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'setting',
-          label: gettext('Setting'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'unit',
-          label: gettext('Unit'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'short_desc',
-          label: gettext('Description'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        // To align subnode controls properly
-        $(div_server_activity).addClass('pg-el-container');
-        $(div_server_activity).attr('el', 'sm');
-
-        // Render the tabs, but only get data for the activity tab for now
-        pgAdmin.Dashboard.render_grid(
-          div_server_activity, url_for('dashboard.activity'), server_activity_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_locks, url_for('dashboard.locks'), server_locks_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_prepared, url_for('dashboard.prepared'), server_prepared_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_config, url_for('dashboard.config'), server_config_columns
-        );
-
-        pgAdmin.Dashboard.render_grid_data(div_server_activity);
-
-        // (Re)render the appropriate tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
-          self.renderTab(e, tab_grid_map);
-        });
-
-        $('#btn_refresh').off('click').on('click', () => {
-          let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
-          pgAdmin.Dashboard.render_grid_data(currGrid);
-        });
-      }
-    },
-    reflectPreferencesDatabase: function() {
-      var self = this;
-      var div_database_activity = document.getElementById('database_activity');
-      var div_database_locks = document.getElementById('database_locks');
-      var div_database_prepared = document.getElementById('database_prepared');
-
-      var tab_grid_map = {
-        'tab_database_activity': div_database_activity,
-        'tab_database_locks': div_database_locks,
-        'tab_database_prepared': div_database_prepared,
-      };
-
-      // Display server activity
-      if (self.preferences.show_activity) {
-        var database_activity_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'usename',
-          label: gettext('User'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'application_name',
-          label: gettext('Application'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'client_addr',
-          label: gettext('Client'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'backend_start',
-          label: gettext('Backend start'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'state',
-          label: gettext('State'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        if (self.version < 90600) {
-          database_activity_columns = database_activity_columns.concat(
-            [{
-              name: 'waiting',
-              label: gettext('Waiting?'),
-              editable: false,
-              cell: 'string',
-            }]);
-        } else {
-          database_activity_columns = database_activity_columns.concat(
-            [{
-              name: 'wait_event',
-              label: gettext('Wait event'),
-              editable: false,
-              cell: 'string',
-            }, {
-              name: 'blocking_pids',
-              label: gettext('Blocking PIDs'),
-              editable: false,
-              cell: 'string',
-            }]);
-        }
-
-        var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
-
-        var subNodeFieldsModel = Backform.generateViewSchema(
-          null, newActiveQueryDetailsModel, 'create', null, null, true
-        );
-
-        // Add version to each field
-        _.each(subNodeFieldsModel[0].fields, function(obj) {
-          obj['version'] = self.version;
-        });
-
-        // Add cancel active query button
-        database_activity_columns.unshift({
-          name: 'pg-backform-expand',
-          label: '',
-          cell: SessionDetailsCell,
-          cell_priority: -1,
-          postgres_version: self.version,
-          schema: subNodeFieldsModel,
-        });
-
-        database_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'cancel',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-        database_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'terminate',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        var database_locks_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'locktype',
-          label: gettext('Lock type'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'relation',
-          label: gettext('Target relation'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'page',
-          label: gettext('Page'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'tuple',
-          label: gettext('Tuple'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualxid',
-          label: gettext('vXID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transactionid',
-          label: gettext('XID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'classid',
-          label: gettext('Class'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'objid',
-          label: gettext('Object ID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualtransaction',
-          label: gettext('vXID (owner)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'mode',
-          label: gettext('Mode'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'granted',
-          label: gettext('Granted?'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var database_prepared_columns = [{
-          name: 'git',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'Owner',
-          label: gettext('Owner'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transaction',
-          label: gettext('XID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'prepared',
-          label: gettext('Prepared at'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        // To align subnode controls properly
-        $(div_database_activity).addClass('pg-el-container');
-        $(div_database_activity).attr('el', 'sm');
-
-        // Render the tabs, but only get data for the activity tab for now
-        pgAdmin.Dashboard.render_grid(
-          div_database_activity, url_for('dashboard.activity'), database_activity_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_database_locks, url_for('dashboard.locks'), database_locks_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_database_prepared, url_for('dashboard.prepared'), database_prepared_columns
-        );
-
-        pgAdmin.Dashboard.render_grid_data(div_database_activity);
-
-        // (Re)render the appropriate tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
-          self.renderTab(e, tab_grid_map);
-        });
-
-        $('#btn_refresh').off('click').on('click', () => {
-          let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
-          pgAdmin.Dashboard.render_grid_data(currGrid);
-        });
-      }
-    },
-    toggleVisibility: function(visible, closed=false) {
-      dashboardVisible = visible;
-      if(closed) {
-        this.chartsDomObj && this.chartsDomObj.unmount();
-      } else {
-        var t = pgBrowser.tree,
-          i = t ? t.selected() : 0,
-          d = i && t.itemData(i);
-
-        this.chartsDomObj && this.chartsDomObj.setPageVisible(dashboardVisible);
-        this.object_selected(i, d);
-      }
-    },
-    can_take_action: function(m) {
-      // We will validate if user is allowed to cancel the active query
-      // If there is only one active session means it probably our main
-      // connection session
-      var active_sessions = m.collection.where({
-          'state': 'active',
-        }),
-        pg_version = this.get('postgres_version') || null,
-        cell_action = this.get('cell_action') || null,
-        is_cancel_session = cell_action === 'cancel',
-        txtMessage;
-
-      // With PG10, We have background process showing on dashboard
-      // We will not allow user to cancel them as they will fail with error
-      // anyway, so better usability we will throw our on notification
-
-      // Background processes do not have database field populated
-      if (pg_version && pg_version >= 100000 && !m.get('datname')) {
-        if (is_cancel_session) {
-          txtMessage = gettext('You cannot cancel background worker processes.');
-        } else {
-          txtMessage = gettext('You cannot terminate background worker processes.');
-        }
-        Notify.info(txtMessage);
-        return false;
-        // If it is the last active connection on maintenance db then error out
-      } else if (maintenance_database == m.get('datname') &&
-        m.get('state') == 'active' && active_sessions.length == 1) {
-        if (is_cancel_session) {
-          txtMessage = gettext('You are not allowed to cancel the main active session.');
-        } else {
-          txtMessage = gettext('You are not allowed to terminate the main active session.');
-        }
-        Notify.error(txtMessage);
-        return false;
-      } else if (is_cancel_session && m.get('state') == 'idle') {
-        // If this session is already idle then do nothing
-        Notify.info(
-          gettext('The session is already in idle state.')
-        );
-        return false;
-      } else if (can_signal_backend) {
-        // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
-        return true;
-      } else if (is_super_user) {
-        // Super user can do anything
-        return true;
-      } else if (current_user && current_user == m.get('usename')) {
-        // Non-super user can cancel only their active queries
-        return true;
-      } else {
-        // Do not allow to cancel someone else session to non-super user
-        if (is_cancel_session) {
-          txtMessage = gettext('Superuser privileges are required to cancel another users query.');
-        } else {
-          txtMessage = gettext('Superuser privileges are required to terminate another users query.');
-        }
-        Notify.error(txtMessage);
-        return false;
-      }
-    },
-  };
-
-  return pgAdmin.Dashboard;
-});
diff --git a/web/pgadmin/dashboard/static/js/dashboardDummy.js b/web/pgadmin/dashboard/static/js/dashboardDummy.js
new file mode 100644
index 000000000..1836868e1
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/dashboardDummy.js
@@ -0,0 +1,2788 @@
+// //  /////////////////////////////////////////////////////////////
+// //  //
+// //  // pgAdmin 4 - PostgreSQL Tools
+// //  //
+// //  // Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// //  // This software is released under the PostgreSQL Licence
+// //  //
+// //  //////////////////////////////////////////////////////////////
+
+// //  import Notify from '../../../static/js/helpers/Notifier';
+
+// //  define('pgadmin.dashboard', [
+// //   'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
+// //   'sources/pgadmin', 'backbone', 'backgrid',
+// //   'pgadmin.alertifyjs', 'pgadmin.backform', 'sources/nodes/dashboard',
+// //   'sources/window', './ChartsDOM', 'pgadmin.browser', 'bootstrap', 'wcdocker',
+// //  ], function(
+// //   url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid,
+// //   Alertify, Backform, NodesDashboard, pgWindow, ChartsDOM
+// //  ) {
+
+// //   pgAdmin.Browser = pgAdmin.Browser || {};
+// //   var pgBrowser = pgAdmin.Browser;
+
+// //   /* Return back, this has been called more than once */
+// //   if (pgAdmin.Dashboard)
+// //     return;
+
+// //   var dashboardVisible = true,
+// //     cancel_query_url = '',
+// //     terminate_session_url = '',
+// //     is_super_user = false,
+// //     current_user, maintenance_database,
+// //     is_server_dashboard = false,
+// //     is_database_dashboard = false,
+// //     can_signal_backend = false;
+
+// //   // Custom BackGrid cell, Responsible for cancelling active sessions
+// //   var customDashboardActionCell = Backgrid.Extension.DeleteCell.extend({
+// //     render: function() {
+// //       this.$el.empty();
+// //       var self = this,
+// //         cell_action = self.column.get('cell_action');
+// //       // if cancel query button then
+// //       if (cell_action === 'cancel') {
+// //         this.$el.html(
+// //           '<i class=\'fa fa-stop\' data-toggle=\'tooltip\' ' +
+// //           'title=\'' + gettext('Cancel the active query') +
+// //           '\' aria-label=\''+ gettext('Cancel the active query') +'\'></i>'
+// //         );
+// //       } else {
+// //         this.$el.html(
+// //           '<i class=\'fa fa-times-circle text-danger\' data-toggle=\'tooltip\' ' +
+// //           'title=\'' + gettext('Terminate the session') +
+// //           '\' aria-label=\''+ gettext('Terminate the session') +'\'></i>'
+// //         );
+// //       }
+// //       this.$el.attr('tabindex', 0);
+// //       this.$el.on('keydown', function(e) {
+// //         // terminating session or cancel the active query.
+// //         if (e.keyCode == 32) {
+// //           self.$el.click();
+// //         }
+// //       });
+// //       this.delegateEvents();
+// //       return this;
+// //     },
+// //     deleteRow: function(e) {
+// //       var self = this,
+// //         title, txtConfirm, txtSuccess, txtError, action_url,
+// //         cell_action = self.column.get('cell_action');
+
+// //       e.preventDefault();
+
+// //       var canDeleteRow = Backgrid.callByNeed(
+// //         self.column.get('canDeleteRow'), self.column, self.model
+// //       );
+// //       // If we are not allowed to cancel the query, return from here
+// //       if (!canDeleteRow)
+// //         return;
+
+// //       // This will refresh the grid
+// //       let refresh_grid = () => {
+// //         $('#btn_refresh').trigger('click');
+// //       };
+
+// //       if (cell_action === 'cancel') {
+// //         title = gettext('Cancel Active Query?');
+// //         txtConfirm = gettext('Are you sure you wish to cancel the active query?');
+// //         txtSuccess = gettext('Active query cancelled successfully.');
+// //         txtError = gettext('An error occurred whilst cancelling the active query.');
+// //         action_url = cancel_query_url + self.model.get('pid');
+// //       } else {
+// //         title = gettext('Terminate Session?');
+// //         txtConfirm = gettext('Are you sure you wish to terminate the session?');
+// //         txtSuccess = gettext('Session terminated successfully.');
+// //         txtError = gettext('An error occurred whilst terminating the active query.');
+// //         action_url = terminate_session_url + self.model.get('pid');
+// //       }
+
+// //       Notify.confirm(
+// //         title, txtConfirm,
+// //         function() {
+// //           $.ajax({
+// //             url: action_url,
+// //             type: 'DELETE',
+// //           })
+// //             .done(function(res) {
+// //               if (res == gettext('Success')) {
+// //                 Notify.success(txtSuccess);
+// //                 refresh_grid();
+// //               } else {
+// //                 Notify.error(txtError);
+// //               }
+// //             })
+// //             .fail(function(xhr, status, error) {
+// //               Notify.pgRespErrorNotify(xhr, error);
+// //             });
+// //         },
+// //         function() {
+// //           return true;
+// //         }
+// //       );
+// //     },
+// //   });
+
+
+// //   // Subnode Cell, which will display subnode control
+// //   var SessionDetailsCell = Backgrid.Extension.ObjectCell.extend({
+// //     enterEditMode: function() {
+// //       // Notify that we are about to enter in edit mode for current cell.
+// //       this.model.trigger('enteringEditMode', [this]);
+
+// //       Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
+// //       /* Make sure - we listen to the click event */
+// //       this.delegateEvents();
+// //       var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model);
+
+// //       if (editable) {
+// //         this.$el.html(
+// //           '<i class=\'fa fa-caret-down subnode-edit-in-process\'></i>'
+// //         );
+// //         this.model.trigger(
+// //           'pg-sub-node:opened', this.model, this
+// //         );
+// //       }
+// //     },
+// //     render: function() {
+// //       this.$el.empty();
+// //       this.$el.html(
+// //         '<i class=\'fa fa-caret-right\' data-toggle=\'tooltip\' ' +
+// //         'title=\'' + gettext('View the active session details') +
+// //         '\' aria-label=\''+ gettext('View the active session details') +'\'></i>'
+// //       );
+// //       this.delegateEvents();
+// //       if (this.grabFocus)
+// //         this.$el.trigger('focus');
+// //       return this;
+// //     },
+// //   });
+
+// //   // Subnode Model
+// //   var ActiveQueryDetailsModel = Backbone.Model.extend({
+// //     defaults: {
+// //       version: null,
+// //       /* Postgres version */
+// //     },
+// //     schema: [{
+// //       id: 'backend_type',
+// //       label: gettext('Backend type'),
+// //       type: 'text',
+// //       editable: true,
+// //       readonly: true,
+// //       group: gettext('Details'),
+// //       visible: function() {
+// //         return this.version >= 100000;
+// //       },
+// //     }, {
+// //       id: 'query_start',
+// //       label: gettext('Query started at'),
+// //       type: 'text',
+// //       editable: false,
+// //       readonly: true,
+// //       group: gettext('Details'),
+// //     }, {
+// //       id: 'state_change',
+// //       label: gettext('Last state changed at'),
+// //       type: 'text',
+// //       editable: true,
+// //       readonly: true,
+// //       group: gettext('Details'),
+// //     }, {
+// //       id: 'query',
+// //       label: gettext('SQL'),
+// //       type: 'text',
+// //       editable: true,
+// //       readonly: true,
+// //       control: Backform.SqlFieldControl,
+// //       group: gettext('Details'),
+// //     }],
+// //   });
+
+// //   pgAdmin.Dashboard = {
+// //     init: function() {
+// //       if (this.initialized)
+// //         return;
+
+// //       this.initialized = true;
+// //       this.chartsDomObj = null;
+
+// //       this.sid = this.did = -1;
+// //       this.version = -1;
+
+
+// //       // Bind the Dashboard object with the 'object_selected' function
+// //       var selected = this.object_selected.bind(this);
+// //       var disconnected = this.object_disconnected.bind(this);
+
+// //       // Listen for selection of any of object
+// //       pgBrowser.Events.on('pgadmin-browser:tree:selected', selected);
+
+// //       // Listen for server disconnected event
+// //       pgBrowser.Events.on('pgadmin:server:disconnect', disconnected);
+
+// //       // Load the default welcome dashboard
+// //       var url = url_for('dashboard.index');
+
+// //       var dashboardPanel = pgBrowser.panels['dashboard'].panel;
+// //       if (dashboardPanel) {
+// //         var div = dashboardPanel.layout().scene().find('.pg-panel-content');
+// //         if (div) {
+// //           var ajaxHook = function() {
+// //             $.ajax({
+// //               url: url,
+// //               type: 'GET',
+// //               dataType: 'html',
+// //             })
+// //               .done(function(data) {
+// //                 $(div).html(data);
+// //               })
+// //               .fail(function(xhr, error) {
+// //                 self.onFail(xhr, error, div, ajaxHook);
+// //               });
+// //           };
+// //           $(div).html(
+// //             '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
+// //           );
+// //           ajaxHook();
+
+// //           // Cache the current IDs for next time
+// //           $(dashboardPanel).data('sid', -1);
+// //           $(dashboardPanel).data('did', -1);
+// //         }
+// //       }
+// //     },
+
+// //     onFail: function(xhr, error, div, ajaxHook) {
+// //       Notify.pgNotifier(
+// //         error, xhr,
+// //         gettext('An error occurred whilst loading the dashboard.'),
+// //         function(msg) {
+// //           if(msg === 'CRYPTKEY_SET') {
+// //             ajaxHook();
+// //           } else {
+// //             $(div).html(
+// //               '<div class="pg-panel-message" role="alert">' + gettext('An error occurred whilst loading the dashboard.') + '</div>'
+// //             );
+// //           }
+// //         }
+// //       );
+// //     },
+
+// //     // Handle Server Disconnect
+// //     object_disconnected: function() {
+// //       let item = pgBrowser.tree.selected(),
+// //         itemData = item && pgBrowser.tree.itemData(item);
+
+// //       // The server connected may not be the same one, which was selected, and
+// //       // we do care out the current selected one only.
+// //       if (item.length != 0) {
+// //         this.object_selected(item, itemData);
+// //       }
+// //     },
+
+// //     // Handle treeview clicks
+// //     object_selected: function(item, itemData) {
+// //       let self = this;
+
+// //       if (itemData && itemData._type) {
+// //         var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
+// //           url = NodesDashboard.url(itemData, item, treeHierarchy);
+
+// //         if (url === null) {
+// //           url = url_for('dashboard.index');
+// //           self.version = (treeHierarchy.server && treeHierarchy.server.version) || 0;
+
+// //           cancel_query_url = url + 'cancel_query/';
+// //           terminate_session_url = url + 'terminate_session/';
+
+// //           // Check if user is super user
+// //           var server = treeHierarchy['server'];
+// //           maintenance_database = (server && server.db) || null;
+// //           can_signal_backend = (server && server.user) ? server.user.can_signal_backend : false;
+
+// //           if (server && server.user && server.user.is_superuser) {
+// //             is_super_user = true;
+// //           } else {
+// //             is_super_user = false;
+// //             // Set current user
+// //             current_user = (server && server.user) ? server.user.name : null;
+// //           }
+
+// //           if ('database' in treeHierarchy) {
+// //             self.sid = treeHierarchy.server._id;
+// //             self.did = treeHierarchy.database._id;
+// //             is_server_dashboard = false;
+// //             is_database_dashboard = true;
+// //             url += self.sid + '/' + self.did;
+// //             cancel_query_url += self.sid + '/' + self.did + '/';
+// //             terminate_session_url += self.sid + '/' + self.did + '/';
+// //           } else if ('server' in treeHierarchy) {
+// //             self.sid = treeHierarchy.server._id;
+// //             self.did = -1;
+// //             is_server_dashboard = true;
+// //             is_database_dashboard = false;
+// //             url += self.sid;
+// //             cancel_query_url += self.sid + '/';
+// //             terminate_session_url += self.sid + '/';
+// //           } else {
+// //             is_server_dashboard = is_database_dashboard = false;
+// //           }
+// //         }
+// //         else {
+// //           is_server_dashboard = is_database_dashboard = false;
+// //         }
+
+// //         var dashboardPanel = pgBrowser.panels['dashboard'].panel;
+// //         if (dashboardPanel) {
+// //           var div = dashboardPanel.layout().scene().find(
+// //             '.pg-panel-content'
+// //           );
+
+// //           if (div) {
+// //             if (itemData.connected || _.isUndefined(itemData.connected)) {
+// //               // Avoid unnecessary reloads
+// //               if (
+// //                 url !== $(dashboardPanel).data('dashboard_url') || (
+// //                   url === $(dashboardPanel).data('dashboard_url') &&
+// //                   $(dashboardPanel).data('server_status') == false
+// //                 )
+// //               ) {
+// //                 this.chartsDomObj && this.chartsDomObj.unmount();
+// //                 $(div).empty();
+
+// //                 let ajaxHook = function() {
+// //                   $.ajax({
+// //                     url: url,
+// //                     type: 'GET',
+// //                     dataType: 'html',
+// //                   })
+// //                     .done(function(data) {
+// //                       $(div).html(data);
+// //                       self.init_dashboard();
+// //                     })
+// //                     .fail(function(xhr, error) {
+// //                       self.onFail(xhr, error, div, ajaxHook);
+// //                     });
+// //                 };
+// //                 $(div).html(
+// //                   '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
+// //                 );
+// //                 ajaxHook();
+// //                 $(dashboardPanel).data('server_status', true);
+// //               }
+// //             } else {
+// //               this.chartsDomObj && this.chartsDomObj.unmount();
+// //               $(div).html(
+// //                 '<div class="pg-panel-message" role="alert">' + gettext('Please connect to the selected server to view the dashboard.') + '</div>'
+// //               );
+// //               $(dashboardPanel).data('server_status', false);
+// //             }
+// //             // Cache the current IDs for next time
+// //             $(dashboardPanel).data('dashboard_url', url);
+// //           }
+// //         }
+// //       }
+// //     },
+
+// //      Handler function to support the "Add Server" link
+// //     add_new_server: function() {
+// //       if (pgBrowser && pgBrowser.tree) {
+// //         var i = _.isUndefined(pgBrowser.tree.selected()) ?
+// //             pgBrowser.tree.first(null, false):
+// //             pgBrowser.tree.selected(),
+// //           serverModule = require('pgadmin.node.server'),
+// //           itemData = pgBrowser.tree.itemData(i);
+
+// //         while (itemData && itemData._type != 'server_group') {
+// //           i = pgBrowser.tree.next(i);
+// //           itemData = pgBrowser.tree.itemData(i);
+// //         }
+
+// //         if (!itemData) {
+// //           return;
+// //         }
+
+// //         if (serverModule) {
+// //           serverModule.callbacks.show_obj_properties.apply(
+// //             serverModule, [{
+// //               action: 'create',
+// //             }, i]
+// //           );
+// //         }
+// //       }
+// //     },
+
+// //     // Render a grid
+// //     render_grid: function(container, url, columns) {
+// //       var Datum = Backbone.Model.extend({}),
+// //         self = this;
+
+// //       var path = url + self.sid;
+// //       if (self.did != -1) {
+// //         path += '/' + self.did;
+// //       }
+
+// //       var Data = Backbone.Collection.extend({
+// //         model: Datum,
+// //         url: path,
+// //         mode: 'client',
+// //       });
+
+// //       var data = new Data();
+
+// //       var HighlightedRow = Backgrid.Row.extend({
+// //         render: function() {
+// //           Backgrid.Row.prototype.render.call(this);
+// //           var row_type = this.model.get('row_type');
+
+// //           if (_.isUndefined(row_type) || _.isNull(row_type)) {
+// //             this.$el.removeClass('alert');
+// //             this.$el.removeClass('warning');
+// //           } else if (row_type === 'warning') {
+// //             this.$el.addClass('warning');
+// //           } else if (row_type === 'alert') {
+// //             this.$el.addClass('alert');
+// //           }
+
+// //           return this;
+// //         }
+// //       });
+
+// //       // Set up the grid
+// //       var grid = new Backgrid.Grid({
+// //         emptyText: gettext('No data found'),
+// //         columns: columns,
+// //         collection: data,
+// //         className: 'backgrid presentation table table-bordered table-noouter-border table-hover',
+// //         row: HighlightedRow
+// //       });
+
+// //       // Render the grid
+// //       $(container).empty();
+// //       $(container).append(grid.render().el);
+
+// //       // Initialize a client-side filter to filter on the client
+// //       // mode pageable collection's cache.
+// //       var filter = new Backgrid.Extension.ClientSideFilter({
+// //         collection: data,
+// //       });
+
+// //       filter.setCustomSearchBox($('#txtGridSearch'));
+// //       // Stash objects for future use
+// //       $(container).data('data', data);
+// //       $(container).data('grid', grid);
+// //       $(container).data('filter', filter);
+// //     },
+// //     __loadMoreRows: function(e) {
+// //       let elem = e.currentTarget;
+// //       if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
+// //         if (this.data.length > 0) {
+// //           this.local_grid.collection.add(this.data.splice(0, 50));
+// //         }
+// //       }
+// //     },
+// //     // Render the data in a grid
+// //     render_grid_data: function(container) {
+// //       var that = this;
+// //       var data = $(container).data('data'),
+// //         grid = $(container).data('grid'),
+// //         filter = $(container).data('filter');
+
+// //       if (_.isUndefined(data)) {
+// //         return null;
+// //       }
+
+// //       data.fetch({
+// //         reset: true,
+// //         success: function(res) {
+// //           that.data = res.models;
+// //           that.local_grid = grid;
+// //           grid.collection.reset(that.data.splice(0,50));
+
+// //           // If we're showing an error, remove it, and replace the grid & filter
+// //           if ($(container).hasClass('grid-error')) {
+// //             $(container).removeClass('grid-error');
+// //             $(container).html(grid.render().el);
+// //             $(filter.el).show();
+// //           }
+
+// //           if(that.data.length > 50) {
+// //             // Listen scroll event to load more rows
+// //             $('.wcScrollableY').on('scroll', that.__loadMoreRows.bind(that));
+// //           } else {
+// //             // Listen scroll event to load more rows
+// //             $('.wcScrollableY').off('scroll', that.__loadMoreRows);
+// //           }
+
+// //           // Re-apply search criteria
+// //           filter.search();
+// //         },
+// //         error: function(model, xhr) {
+// //           let err = '';
+// //           let msg = '';
+// //           let cls = 'info';
+
+// //           if (xhr.readyState === 0) {
+// //             msg = gettext('Not connected to the server or the connection to the server has been closed.');
+// //           } else {
+// //             err = JSON.parse(xhr.responseText);
+// //             msg = err.errormsg;
+
+// //             // If we get a 428, it means the server isn't connected
+// //             if (xhr.status === 428) {
+// //               if (_.isUndefined(msg) || _.isNull(msg)) {
+// //                 msg = gettext('Please connect to the selected server to view the table.');
+// //               }
+// //             } else {
+// //               msg = gettext('An error occurred whilst rendering the table.');
+// //               cls = 'error';
+// //             }
+// //           }
+
+// //           // Replace the content with the error, if not already present. Always update the message
+// //           if (!$(container).hasClass('grid-error')) {
+// //             $(filter.el).hide();
+// //             $(container).addClass('grid-error');
+// //           }
+
+// //           $(container).html(
+// //             '<div class="pg-panel-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
+// //           );
+
+// //           // Try again
+// //           setTimeout(function() {
+// //             pgAdmin.Dashboard.render_grid_data(container, data);
+// //           }, 5000);
+// //         },
+// //       });
+// //     },
+
+// //     // Rock n' roll on the dashboard
+// //     init_dashboard: function() {
+// //       let self = this;
+
+// //       this.chartsDomObj = new ChartsDOM.default(
+// //         document.getElementById('dashboard-graphs'),
+// //         self.preferences,
+// //         self.sid,
+// //         self.did,
+// //         $('.dashboard-container')[0].clientHeight <=0 ? false : true
+// //       );
+
+// //       /* Cache may take time to load for the first time
+// //        * Keep trying till available
+// //        */
+// //       let cacheIntervalId = setInterval(function() {
+// //         try {
+// //           if(pgWindow.default.pgAdmin.Browser.preference_version() > 0) {
+// //             clearInterval(cacheIntervalId);
+// //             self.reflectPreferences();
+// //           }
+// //         }
+// //         catch(err) {
+// //           clearInterval(cacheIntervalId);
+// //           throw err;
+// //         }
+// //       },0);
+
+// //       /* Register for preference changed event broadcasted */
+// //       pgBrowser.onPreferencesChange('dashboards', function() {
+// //         self.reflectPreferences();
+// //       });
+// //     },
+
+// //     reflectPreferences: function() {
+// //       var self = this;
+// //       self.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('dashboards');
+// //       this.chartsDomObj.reflectPreferences(self.preferences);
+
+// //       if(is_server_dashboard || is_database_dashboard) {
+// //         if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
+// //           $('#dashboard-activity').removeClass('dashboard-hidden');
+// //         }
+// //         else if(!self.preferences.show_activity) {
+// //           $('#dashboard-activity').addClass('dashboard-hidden');
+// //         }
+
+// //         if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
+// //           $('#dashboard-activity').removeClass('dashboard-hidden');
+// //         }
+// //         else if(!self.preferences.show_activity) {
+// //           $('#dashboard-activity').addClass('dashboard-hidden');
+// //         }
+
+// //         /* Dashboard specific preferences can be updated in the
+// //          * appropriate functions
+// //          */
+// //         if(is_server_dashboard) {
+// //           self.reflectPreferencesServer();
+// //         }
+// //         else if(is_database_dashboard) {
+// //           self.reflectPreferencesDatabase();
+// //         }
+// //       }
+// //     },
+
+// //     renderTab: function(e, tab_grid_map) {
+// //       let prevGrid = tab_grid_map[$(e.relatedTarget).attr('aria-controls')];
+// //       $(prevGrid).data('filtertext', $('#txtGridSearch').val());
+
+// //       let currGrid = tab_grid_map[$(e.target).attr('aria-controls')];
+// //       $('#txtGridSearch').val($(currGrid).data('filtertext'));
+// //       pgAdmin.Dashboard.render_grid_data(currGrid);
+// //     },
+
+// //     reflectPreferencesServer: function() {
+// //       var self = this;
+// //       var $dashboardContainer = $('.dashboard-container');
+// //       var div_server_activity = $dashboardContainer.find('#server_activity').get(0);
+// //       var div_server_locks = $dashboardContainer.find('#server_locks').get(0);
+// //       var div_server_prepared = $dashboardContainer.find('#server_prepared').get(0);
+// //       var div_server_config = $dashboardContainer.find('#server_config').get(0);
+
+// //       var tab_grid_map = {
+// //         'tab_server_activity': div_server_activity,
+// //         'tab_server_locks': div_server_locks,
+// //         'tab_server_prepared': div_server_prepared,
+// //         'tab_server_config': div_server_config,
+// //       };
+
+// //       // Display server activity
+// //       if (self.preferences.show_activity) {
+// //         var server_activity_columns = [{
+// //           name: 'pid',
+// //           label: gettext('PID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'datname',
+// //           label: gettext('Database'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'usename',
+// //           label: gettext('User'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'application_name',
+// //           label: gettext('Application'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'client_addr',
+// //           label: gettext('Client'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'backend_start',
+// //           label: gettext('Backend start'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'state',
+// //           label: gettext('State'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         if (self.version < 90600) {
+// //           server_activity_columns = server_activity_columns.concat(
+// //             [{
+// //               name: 'waiting',
+// //               label: gettext('Waiting?'),
+// //               editable: false,
+// //               cell: 'string',
+// //             }]);
+// //         } else {
+// //           server_activity_columns = server_activity_columns.concat(
+// //             [{
+// //               name: 'wait_event',
+// //               label: gettext('Wait event'),
+// //               editable: false,
+// //               cell: 'string',
+// //             }, {
+// //               name: 'blocking_pids',
+// //               label: gettext('Blocking PIDs'),
+// //               editable: false,
+// //               cell: 'string',
+// //             }]);
+// //         }
+
+// //         var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
+
+// //         var subNodeFieldsModel = Backform.generateViewSchema(
+// //           null, newActiveQueryDetailsModel, 'create', null, null, true
+// //         );
+
+// //         // Add version to each field
+// //         _.each(subNodeFieldsModel[0].fields, function(obj) {
+// //           obj['version'] = self.version;
+// //         });
+
+// //         // Add cancel active query button
+// //         server_activity_columns.unshift({
+// //           name: 'pg-backform-expand',
+// //           label: '',
+// //           cell: SessionDetailsCell,
+// //           cell_priority: -1,
+// //           postgres_version: self.version,
+// //           schema: subNodeFieldsModel,
+// //         });
+
+// //         // Add cancel active query button
+// //         server_activity_columns.unshift({
+// //           name: 'pg-backform-delete',
+// //           label: '',
+// //           cell: customDashboardActionCell,
+// //           cell_action: 'cancel',
+// //           editable: false,
+// //           cell_priority: -1,
+// //           canDeleteRow: pgAdmin.Dashboard.can_take_action,
+// //           postgres_version: self.version,
+// //         });
+
+// //         server_activity_columns.unshift({
+// //           name: 'pg-backform-delete',
+// //           label: '',
+// //           cell: customDashboardActionCell,
+// //           cell_action: 'terminate',
+// //           editable: false,
+// //           cell_priority: -1,
+// //           canDeleteRow: pgAdmin.Dashboard.can_take_action,
+// //           postgres_version: self.version,
+// //         });
+
+// //         var server_locks_columns = [{
+// //           name: 'pid',
+// //           label: gettext('PID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'datname',
+// //           label: gettext('Database'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'locktype',
+// //           label: gettext('Lock type'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'relation',
+// //           label: gettext('Target relation'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'page',
+// //           label: gettext('Page'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'tuple',
+// //           label: gettext('Tuple'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'virtualxid',
+// //           label: gettext('vXID (target)'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'transactionid',
+// //           label: gettext('XID (target)'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'classid',
+// //           label: gettext('Class'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'objid',
+// //           label: gettext('Object ID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'virtualtransaction',
+// //           label: gettext('vXID (owner)'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'mode',
+// //           label: gettext('Mode'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'granted',
+// //           label: gettext('Granted?'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         var server_prepared_columns = [{
+// //           name: 'git',
+// //           label: gettext('Name'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'database',
+// //           label: gettext('Database'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'Owner',
+// //           label: gettext('Owner'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'transaction',
+// //           label: gettext('XID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'prepared',
+// //           label: gettext('Prepared at'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         var server_config_columns = [{
+// //           name: 'name',
+// //           label: gettext('Name'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'category',
+// //           label: gettext('Category'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'setting',
+// //           label: gettext('Setting'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'unit',
+// //           label: gettext('Unit'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'short_desc',
+// //           label: gettext('Description'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         // To align subnode controls properly
+// //         $(div_server_activity).addClass('pg-el-container');
+// //         $(div_server_activity).attr('el', 'sm');
+
+// //         // Render the tabs, but only get data for the activity tab for now
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_server_activity, url_for('dashboard.activity'), server_activity_columns
+// //         );
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_server_locks, url_for('dashboard.locks'), server_locks_columns
+// //         );
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_server_prepared, url_for('dashboard.prepared'), server_prepared_columns
+// //         );
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_server_config, url_for('dashboard.config'), server_config_columns
+// //         );
+
+// //         pgAdmin.Dashboard.render_grid_data(div_server_activity);
+
+// //         // (Re)render the appropriate tab
+// //         $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
+// //           self.renderTab(e, tab_grid_map);
+// //         });
+
+// //         $('#btn_refresh').off('click').on('click', () => {
+// //           let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
+// //           pgAdmin.Dashboard.render_grid_data(currGrid);
+// //         });
+// //       }
+// //     },
+// //     reflectPreferencesDatabase: function() {
+// //       var self = this;
+// //       var div_database_activity = document.getElementById('database_activity');
+// //       var div_database_locks = document.getElementById('database_locks');
+// //       var div_database_prepared = document.getElementById('database_prepared');
+
+// //       var tab_grid_map = {
+// //         'tab_database_activity': div_database_activity,
+// //         'tab_database_locks': div_database_locks,
+// //         'tab_database_prepared': div_database_prepared,
+// //       };
+
+// //       // Display server activity
+// //       if (self.preferences.show_activity) {
+// //         var database_activity_columns = [{
+// //           name: 'pid',
+// //           label: gettext('PID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'usename',
+// //           label: gettext('User'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'application_name',
+// //           label: gettext('Application'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'client_addr',
+// //           label: gettext('Client'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'backend_start',
+// //           label: gettext('Backend start'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'state',
+// //           label: gettext('State'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         if (self.version < 90600) {
+// //           database_activity_columns = database_activity_columns.concat(
+// //             [{
+// //               name: 'waiting',
+// //               label: gettext('Waiting?'),
+// //               editable: false,
+// //               cell: 'string',
+// //             }]);
+// //         } else {
+// //           database_activity_columns = database_activity_columns.concat(
+// //             [{
+// //               name: 'wait_event',
+// //               label: gettext('Wait event'),
+// //               editable: false,
+// //               cell: 'string',
+// //             }, {
+// //               name: 'blocking_pids',
+// //               label: gettext('Blocking PIDs'),
+// //               editable: false,
+// //               cell: 'string',
+// //             }]);
+// //         }
+
+// //         var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
+
+// //         var subNodeFieldsModel = Backform.generateViewSchema(
+// //           null, newActiveQueryDetailsModel, 'create', null, null, true
+// //         );
+
+// //         // Add version to each field
+// //         _.each(subNodeFieldsModel[0].fields, function(obj) {
+// //           obj['version'] = self.version;
+// //         });
+
+// //         // Add cancel active query button
+// //         database_activity_columns.unshift({
+// //           name: 'pg-backform-expand',
+// //           label: '',
+// //           cell: SessionDetailsCell,
+// //           cell_priority: -1,
+// //           postgres_version: self.version,
+// //           schema: subNodeFieldsModel,
+// //         });
+
+// //         database_activity_columns.unshift({
+// //           name: 'pg-backform-delete',
+// //           label: '',
+// //           cell: customDashboardActionCell,
+// //           cell_action: 'cancel',
+// //           editable: false,
+// //           cell_priority: -1,
+// //           canDeleteRow: pgAdmin.Dashboard.can_take_action,
+// //           postgres_version: self.version,
+// //         });
+// //         database_activity_columns.unshift({
+// //           name: 'pg-backform-delete',
+// //           label: '',
+// //           cell: customDashboardActionCell,
+// //           cell_action: 'terminate',
+// //           editable: false,
+// //           cell_priority: -1,
+// //           canDeleteRow: pgAdmin.Dashboard.can_take_action,
+// //           postgres_version: self.version,
+// //         });
+
+// //         var database_locks_columns = [{
+// //           name: 'pid',
+// //           label: gettext('PID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'locktype',
+// //           label: gettext('Lock type'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'relation',
+// //           label: gettext('Target relation'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'page',
+// //           label: gettext('Page'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'tuple',
+// //           label: gettext('Tuple'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'virtualxid',
+// //           label: gettext('vXID (target)'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'transactionid',
+// //           label: gettext('XID (target)'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'classid',
+// //           label: gettext('Class'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'objid',
+// //           label: gettext('Object ID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'virtualtransaction',
+// //           label: gettext('vXID (owner)'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'mode',
+// //           label: gettext('Mode'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'granted',
+// //           label: gettext('Granted?'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         var database_prepared_columns = [{
+// //           name: 'git',
+// //           label: gettext('Name'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'Owner',
+// //           label: gettext('Owner'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'transaction',
+// //           label: gettext('XID'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }, {
+// //           name: 'prepared',
+// //           label: gettext('Prepared at'),
+// //           editable: false,
+// //           cell: 'string',
+// //         }];
+
+// //         // To align subnode controls properly
+// //         $(div_database_activity).addClass('pg-el-container');
+// //         $(div_database_activity).attr('el', 'sm');
+
+// //         // Render the tabs, but only get data for the activity tab for now
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_database_activity, url_for('dashboard.activity'), database_activity_columns
+// //         );
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_database_locks, url_for('dashboard.locks'), database_locks_columns
+// //         );
+// //         pgAdmin.Dashboard.render_grid(
+// //           div_database_prepared, url_for('dashboard.prepared'), database_prepared_columns
+// //         );
+
+// //         pgAdmin.Dashboard.render_grid_data(div_database_activity);
+
+// //         // (Re)render the appropriate tab
+// //         $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
+// //           self.renderTab(e, tab_grid_map);
+// //         });
+
+// //         $('#btn_refresh').off('click').on('click', () => {
+// //           let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
+// //           pgAdmin.Dashboard.render_grid_data(currGrid);
+// //         });
+// //       }
+// //     },
+// //     toggleVisibility: function(visible, closed=false) {
+// //       dashboardVisible = visible;
+// //       if(closed) {
+// //         this.chartsDomObj && this.chartsDomObj.unmount();
+// //       } else {
+// //         var t = pgBrowser.tree,
+// //           i = t ? t.selected() : 0,
+// //           d = i && t.itemData(i);
+
+// //         this.chartsDomObj && this.chartsDomObj.setPageVisible(dashboardVisible);
+// //         this.object_selected(i, d);
+// //       }
+// //     },
+// //     can_take_action: function(m) {
+// //       // We will validate if user is allowed to cancel the active query
+// //       // If there is only one active session means it probably our main
+// //       // connection session
+// //       var active_sessions = m.collection.where({
+// //           'state': 'active',
+// //         }),
+// //         pg_version = this.get('postgres_version') || null,
+// //         cell_action = this.get('cell_action') || null,
+// //         is_cancel_session = cell_action === 'cancel',
+// //         txtMessage;
+
+// //       // With PG10, We have background process showing on dashboard
+// //       // We will not allow user to cancel them as they will fail with error
+// //       // anyway, so better usability we will throw our on notification
+
+// //       // Background processes do not have database field populated
+// //       if (pg_version && pg_version >= 100000 && !m.get('datname')) {
+// //         if (is_cancel_session) {
+// //           txtMessage = gettext('You cannot cancel background worker processes.');
+// //         } else {
+// //           txtMessage = gettext('You cannot terminate background worker processes.');
+// //         }
+// //         Notify.info(txtMessage);
+// //         return false;
+// //         // If it is the last active connection on maintenance db then error out
+// //       } else if (maintenance_database == m.get('datname') &&
+// //         m.get('state') == 'active' && active_sessions.length == 1) {
+// //         if (is_cancel_session) {
+// //           txtMessage = gettext('You are not allowed to cancel the main active session.');
+// //         } else {
+// //           txtMessage = gettext('You are not allowed to terminate the main active session.');
+// //         }
+// //         Notify.error(txtMessage);
+// //         return false;
+// //       } else if (is_cancel_session && m.get('state') == 'idle') {
+// //         // If this session is already idle then do nothing
+// //         Notify.info(
+// //           gettext('The session is already in idle state.')
+// //         );
+// //         return false;
+// //       } else if (can_signal_backend) {
+// //         // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
+// //         return true;
+// //       } else if (is_super_user) {
+// //         // Super user can do anything
+// //         return true;
+// //       } else if (current_user && current_user == m.get('usename')) {
+// //         // Non-super user can cancel only their active queries
+// //         return true;
+// //       } else {
+// //         // Do not allow to cancel someone else session to non-super user
+// //         if (is_cancel_session) {
+// //           txtMessage = gettext('Superuser privileges are required to cancel another users query.');
+// //         } else {
+// //           txtMessage = gettext('Superuser privileges are required to terminate another users query.');
+// //         }
+// //         Notify.error(txtMessage);
+// //         return false;
+// //       }
+// //     },
+// //   };
+
+// //   return pgAdmin.Dashboard;
+// // });
+
+
+
+
+
+
+
+
+// /////////Dashboard.jsx
+
+
+// /////////////////////////////////////////////////////////////
+// //
+// // pgAdmin 4 - PostgreSQL Tools
+// //
+// // Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// // This software is released under the PostgreSQL Licence
+// //
+// //////////////////////////////////////////////////////////////
+
+// import React, { useEffect, useState, useMemo, useRef } from 'react';
+// import gettext from 'sources/gettext';
+// import PropTypes from 'prop-types';
+// import clsx from 'clsx';
+// // import Notify from "../../../../static/js/helpers/Notifier";
+// import getApiInstance from 'sources/api_instance';
+// import PgTable from 'sources/components/PgTable';
+// import { makeStyles } from '@material-ui/core/styles';
+// import url_for from 'sources/url_for';
+// import Graphs from './Graphs';
+// import ReactHtmlParser from 'react-html-parser';
+// import { getURL } from '../../../misc/static/utils/utils';
+// import Notify from '../../../static/js/helpers/Notifier';
+// import { Box, Tab, Tabs } from '@material-ui/core';
+// import { PgIconButton } from '../../../static/js/components/Buttons';
+// import CancelIcon from '@mui/icons-material/Cancel';
+// import SquareIcon from '@mui/icons-material/Square';
+// import ArrowRightOutlinedIcon from '@mui/icons-material/ArrowRightOutlined';
+// import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';
+// import _ from 'lodash';
+
+// import WelcomeDashboard from './WelcomeDashboard';
+
+// import ActiveQuery from './ActiveQuery.ui';
+
+// // function terminateQueryButton(sid, did, row) {
+// //   var terminate_session_url =
+// //     url_for("dashboard.index") + "terminate_session/" + sid + "/" + did,
+// //     title = gettext("Terminate Session?"),
+// //     txtConfirm = gettext("Are you sure you wish to terminate the session?"),
+// //     txtSuccess = gettext("Session terminated successfully."),
+// //     txtError = gettext(
+// //       "An error occurred whilst terminating the active query."
+// //     ),
+// //     action_url = terminate_session_url;
+
+// //   const api = getApiInstance();
+
+// //   return (
+// //     <Button
+// //       variant="outlined"
+// //       startIcon={<CancelIcon sx={{ color: "#d11616" }} />}
+// //       onClick={(e) => {
+// //         action_url += "/" + row.values.pid;
+// //         Notify.confirm(
+// //           title,
+// //           txtConfirm,
+// //           function () {
+// //             api
+// //               .delete(action_url)
+// //               .then(function (res) {
+// //                 if (res == gettext("Success")) {
+// //                   Notify.success(txtSuccess);
+// //                   refresh_grid();
+// //                 } else {
+// //                   Notify.error(txtError);
+// //                 }
+// //               })
+// //               .catch(function (error) {
+// //                 Notify.alert(
+// //                   gettext("Failed to retrieve data from the server."),
+// //                   gettext(error.message)
+// //                 );
+// //               });
+// //           },
+// //           function () {
+// //             return true;
+// //           }
+// //         );
+// //       }}
+// //       color="default"
+// //       aria-label="Cancel the query"
+// //       title={gettext("Cancel the active query")}
+// //     ></Button>
+// //   );
+// // }
+
+// // function cancelQueryButton(sid, did, row) {
+// //   var cancel_query_url =
+// //     url_for("dashboard.index") + "cancel_query/" + sid + "/" + did,
+// //     title = gettext("Cancel Active Query?"),
+// //     txtConfirm = gettext("Are you sure you wish to cancel the active query?"),
+// //     txtSuccess = gettext("Active query cancelled successfully."),
+// //     txtError = gettext("An error occurred whilst cancelling the active query."),
+// //     action_url = cancel_query_url;
+// //   const api = getApiInstance();
+
+// //   return (
+// //     <Button
+// //       variant="outlined"
+// //       startIcon={<SquareIcon />}
+// //       onClick={(e) => {
+// //         action_url += "/" + row.values.pid;
+// //         Notify.confirm(
+// //           title,
+// //           txtConfirm,
+// //           function () {
+// //             api
+// //               .delete(action_url)
+// //               .then(function (res) {
+// //                 if (res == gettext("Success")) {
+// //                   Notify.success(txtSuccess);
+// //                   refresh_grid();
+// //                 } else {
+// //                   Notify.error(txtError);
+// //                 }
+// //               })
+// //               .catch(function (error) {
+// //                 Notify.alert(
+// //                   gettext("Failed to retrieve data from the server."),
+// //                   gettext(error.message)
+// //                 );
+// //               });
+// //           },
+// //           function () {
+// //             return true;
+// //           }
+// //         );
+// //       }}
+// //       color="default"
+// //       aria-label="Cancel the query"
+// //       title={gettext("Cancel the active query")}
+// //     ></Button>
+// //   );
+// // }
+
+// // function getSchema() {
+// //   console.log(new ActiveQuery());
+// //   return (
+// //     <SchemaView
+// //       formType={"dialog"}
+// //       getInitData={() => {
+// //         /*This is intentional (SonarQube)*/
+// //       }}
+// //       viewHelperProps={{ mode: "create" }}
+// //       schema={new ActiveQuery()}
+// //       showFooter={false}
+// //       isTabView={false}
+// //       onDataChange={() => { }}
+// //     />
+// //   );
+// // }
+// // function viewActiveQueryButton(sid, did) {
+// //   return (
+// //     <Button
+// //       variant="outlined"
+// //       startIcon={<PlayArrowIcon />}
+// //       onClick={() => {
+// //         getSchema();
+// //       }}
+// //       color="default"
+// //       aria-label="Cancel the query"
+// //       title={gettext("Cancel the active query")}
+// //     ></Button>
+// //   );
+// // }
+
+// function parseData(data, columns, sid, did) {
+//   var res = [],
+//     name,
+//     value;
+
+//   data.forEach((row) => {
+//     res.push({ ...row, icon: '' });
+//   });
+//   return res;
+// }
+
+// const useStyles = makeStyles((theme) => ({
+//   emptyPanel: {
+//     // height: "auto",
+//     background: theme.palette.grey[400],
+//     overflow: 'hidden',
+//     padding: '8px',
+//     display: 'flex',
+//     flexDirection: 'column',
+//     flexGrow: 1
+
+//   },
+//   cardHeader: {
+//     padding: '0.25rem 0.5rem',
+//     fontWeight: 'bold',
+//     backgroundColor: '#fff',
+//     color: '#222222',
+//     borderColor: '#dde0e6',
+//   },
+//   searchPadding: {
+//     display: 'flex',
+//     flex: 2.5,
+//   },
+//   component: {
+//     padding: '8px',
+//     flexGrow: 1,
+//     minHeight: 0
+//   },
+//   searchInput: {
+//     flex: 1,
+//     // marginTop: 2,
+//     // borderLeft: "none",
+//     // paddingLeft: 5,
+//   },
+//   panelIcon: {
+//     width: '80%',
+//     margin: '0 auto',
+//     marginTop: '25px !important',
+//     position: 'relative',
+//     textAlign: 'center',
+//   },
+//   panelMessage: {
+//     marginLeft: '0.5rem',
+//     fontSize: '0.875rem',
+//   },
+//   tableCell: {
+//     margin: 0,
+//     // padding: theme.spacing(0.5),
+//     // ...theme.mixins.panelBorder.top,
+//     // ...theme.mixins.panelBorder.left,
+//     border: '2px solid #dde0e6',
+//     display: 'flex',
+//     flexDirection: 'column',
+//     flexGrow: 1,
+//     // maxHeight: '10000px'
+//   },
+//   autoResizer: {
+//     width: '100% !important',
+//     height: '100% !important',
+//     minWidth: '100%',
+//     paddingTop: '6px',
+//     minHeight: '10% !important',
+//     // maxHeight:'1000px !important',
+//     // overflowy: 'hidden !important',
+//   },
+//   panelContent: {
+//     flexGrow: 1,
+//     minHeight: 0,
+//   },
+//   nestedControl: {
+//     height: 'auto',
+//   },
+//   searchButton: {
+//     backgroundColor: '#fff',
+//     marginLeft: '2px',
+//     padding: '5px',
+//   },
+// }));
+
+// export default function Dashboard({
+//   nodeData,
+//   node,
+//   item,
+//   pgBrowser,
+//   preferences,
+//   sid,
+//   did,
+//   ...props
+// }) {
+//   const classes = useStyles();
+//   console.log(props.serverConnected);
+//   let tab = ['Sessions', 'Lock', 'Prepared Transactions'];
+
+//   const [dashData, setdashData] = useState([]);
+//   const [alertMsg, setAlertMsg] = useState('');
+//   const [msg, setMsg] = useState('');
+//   const [val, setVal] = useState(0);
+//   const [searchVal, setSearchVal] = React.useState('');
+//   const [canEdit, setCanEdit] = React.useState(false);
+//   const [editRow, setRow] = React.useState(false);
+//   const [schema, setSchema] = React.useState();
+
+//   if (!did) {
+//     tab.push('Configuration');
+//   }
+
+//   const tabChanged = (e, val) => {
+//     setVal(val);
+//   };
+//   // const viewActiveQueryButton = (sid, did) => {
+//   //   return (
+//   //     <Button
+//   //       variant="outlined"
+//   //       startIcon={<PlayArrowIcon />}
+//   //       onClick={() => {
+//   //         setCanEdit(true);
+//   //       }}
+//   //       color="default"
+//   //       aria-label="Cancel the query"
+//   //       title={gettext("Cancel the active query")}
+//   //     ></Button>
+//   //   );
+//   // };
+
+//   const serverConfigColumns = React.useMemo(() => [
+//     {
+//       accessor: 'name',
+//       Header: gettext('Name'),
+//       sortble: true,
+//       resizable: true,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'category',
+//       Header: gettext('Category'),
+//       sortble: true,
+//       resizable: true,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'setting',
+//       Header: gettext('Setting'),
+//       sortble: true,
+//       resizable: true,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'unit',
+//       Header: gettext('Unit'),
+//       editable: false,
+//       cell: 'string',
+//     },
+//     {
+//       accessor: 'short_desc',
+//       Header: gettext('Description'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//   ],[val]);
+
+
+//   const activityrrColumns = React.useMemo(
+//     () => [
+//       {
+//         // Build our expander column
+//         accessor: '',
+//         id: 'expander',
+//         sortble: true,
+//         resizable: true,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 44,
+//         Header: ({ getToggleAllRowsExpandedProps, isAllRowsExpanded }) => (
+//           <span {...getToggleAllRowsExpandedProps()}>
+//             {isAllRowsExpanded ? '👇' : '👉'}
+//           </span>
+//         ),
+//         Cell: ({ row }) =>
+//           // Use the row.canExpand and row.getToggleRowExpandedProps prop getter
+//           // to build the toggle for expanding a row
+//           !row.canExpand ? (
+
+//             <PgIconButton
+//               {...row.getToggleRowExpandedProps({
+//                 style: {
+//                   // We can even use the row.depth property
+//                   // and paddingLeft to indicate the depth
+//                   // of the row
+//                   paddingLeft: `${row.depth * 2}rem`
+//                 }
+//               })}
+//               icon={row.isExpanded ? <ArrowDropDownOutlinedIcon fontSize="small" /> : <ArrowRightOutlinedIcon fontSize="small" />}
+//               onClick={() => {
+//                 row.toggleRowExpanded(!row.isExpanded);
+//                 console.log(row.isExpanded, row);
+//                 setRow(row);
+//                 setSchema(
+//                   new ActiveQuery({
+//                     query: row.original.query,
+//                     backend_type: row.original.backend_type,
+//                     state_change: row.original.state_change,
+//                     query_start: row.original.query_start,
+//                   })
+//                 );
+//               }}
+//               color="default"
+//               aria-label="View the active session details"
+//               title={gettext('View the active session details')}
+//             />
+
+
+
+
+//           //   <PgIconButton
+//           //   icon={row.isExpanded ? <ArrowDropDownOutlinedIcon fontSize="small" /> : <ArrowRightOutlinedIcon fontSize="small" />}
+//           //   onClick={() => {
+//           //     row.toggleRowExpanded(!row.isExpanded);
+//           //     setRow(row);
+//           //     setSchema(
+//           //       new ActiveQuery({
+//           //         query: row.original.query,
+//           //         backend_type: row.original.backend_type,
+//           //         state_change: row.original.state_change,
+//           //         query_start: row.original.query_start,
+//           //       })
+//           //     );
+//           //   }}
+//           //   disabled={!canEditRow}
+//           //   color="default"
+//           //   aria-label="View the active session details"
+//           //   title={gettext("View the active session details")}
+//           // />
+//           ) : null,
+//       },
+//       // {
+//       //   // Build our expander column
+//       //   id: "expander", // Make sure it has an ID
+//       //   Header: ({ getToggleAllRowsExpandedProps, isAllRowsExpanded }) => (
+//       //     <span {...getToggleAllRowsExpandedProps()}>
+//       //       {isAllRowsExpanded ? "👇" : "👉"}
+//       //     </span>
+//       //   ),
+//       //   Cell: ({ row }) =>
+//       //     // Use the row.canExpand and row.getToggleRowExpandedProps prop getter
+//       //     // to build the toggle for expanding a row
+//       //     row.canExpand ? (
+//       //       <span
+//       //         {...row.getToggleRowExpandedProps({
+//       //           style: {
+//       //             // We can even use the row.depth property
+//       //             // and paddingLeft to indicate the depth
+//       //             // of the row
+//       //             paddingLeft: `${row.depth * 2}rem`
+//       //           }
+//       //         })}
+//       //       >
+//       //         {row.isExpanded ? "👇" : "👉"}
+//       //       </span>
+//       //     ) : null
+//       // },
+//       {
+//         accessor: 'terminate_query',
+//         Header: ' ',
+//         sortble: true,
+//         resizable: true,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 44,
+
+//         Cell: ({ row }) => {
+//           var terminate_session_url =
+//               url_for('dashboard.index') +
+//               'terminate_session' +
+//               '/' +
+//               sid +
+//               '/' +
+//               did,
+//             title = gettext('Terminate Session?'),
+//             txtConfirm = gettext(
+//               'Are you sure you wish to terminate the session?'
+//             ),
+//             txtSuccess = gettext('Session terminated successfully.'),
+//             txtError = gettext(
+//               'An error occurred whilst terminating the active query.'
+//             ),
+//             action_url = terminate_session_url;
+
+//           const api = getApiInstance();
+
+//           return (
+//             <PgIconButton
+//               variant="outlined"
+//               icon={<CancelIcon fontSize="small" sx={{ color: '#d11616' }} />}
+//               onClick={(e) => {
+//                 if (
+//                   !canTakeAction(
+//                     row,
+//                     'terminate',
+//                     nodeData,
+//                     props.treeNodeInfo,
+//                     node
+//                   )
+//                 )
+//                   return;
+//                 action_url += '/' + row.values.pid;
+//                 Notify.confirm(
+//                   title,
+//                   txtConfirm,
+//                   function () {
+//                     api
+//                       .delete(action_url)
+//                       .then(function (res) {
+//                         if (res == gettext('Success')) {
+//                           Notify.success(txtSuccess);
+//                           refresh_grid();
+//                         } else {
+//                           Notify.error(txtError);
+//                         }
+//                       })
+//                       .catch(function (error) {
+//                         Notify.alert(
+//                           gettext('Failed to retrieve data from the server.'),
+//                           gettext(error.message)
+//                         );
+//                       });
+//                   },
+//                   function () {
+//                     return true;
+//                   }
+//                 );
+//               }}
+//               color="default"
+//               aria-label="Terminate Session?"
+//               title={gettext('Terminate Session?')}
+//             ></PgIconButton>
+//           );
+//         },
+//       },
+//       {
+//         accessor: 'cancel_Query',
+//         Header: ' ',
+//         sortble: true,
+//         resizable: true,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 44,
+//         Cell: ({ row }) => {
+//           var cancel_query_url =
+//               url_for('dashboard.index') + 'cancel_query' + '/' + sid + '/' + did,
+//             title = gettext('Cancel Active Query?'),
+//             txtConfirm = gettext(
+//               'Are you sure you wish to cancel the active query?'
+//             ),
+//             txtSuccess = gettext('Active query cancelled successfully.'),
+//             txtError = gettext(
+//               'An error occurred whilst cancelling the active query.'
+//             ),
+//             action_url = cancel_query_url;
+//           const api = getApiInstance();
+
+//           return (
+//             <PgIconButton
+//               variant="outlined"
+//               icon={<SquareIcon fontSize="small" />}
+//               onClick={(e) => {
+//                 if (
+//                   !canTakeAction(
+//                     row,
+//                     'cancel',
+//                     nodeData,
+//                     props.treeNodeInfo,
+//                     node
+//                   )
+//                 )
+//                   return;
+//                 action_url += '/' + row.values.pid;
+//                 Notify.confirm(
+//                   title,
+//                   txtConfirm,
+//                   function () {
+//                     api
+//                       .delete(action_url)
+//                       .then(function (res) {
+//                         if (res == gettext('Success')) {
+//                           Notify.success(txtSuccess);
+//                           refresh_grid();
+//                         } else {
+//                           Notify.error(txtError);
+//                         }
+//                       })
+//                       .catch(function (error) {
+//                         Notify.alert(
+//                           gettext('Failed to retrieve data from the server.'),
+//                           gettext(error.message)
+//                         );
+//                       });
+//                   },
+//                   function () {
+//                     return true;
+//                   }
+//                 );
+//               }}
+//               color="default"
+//               aria-label="Cancel the query"
+//               title={gettext('Cancel the active query')}
+//             ></PgIconButton>
+//           );
+//         },
+//       },
+//       // {
+//       //   accessor: "view_active_query",
+//       //   Header: " ",
+//       //   sortble: true,
+//       //   resizable: true,
+//       //   disableGlobalFilter: false,
+//       //   minWidth: 26,
+//       //   maxWidth: 44,
+//       //   // canExpand: true
+//       //   // Cell: (props) => viewActiveQueryButton(sid, did, props.row),
+
+
+
+//       //   Cell: ({ row }) => {
+//       //     console.log(row);
+//       //     let canEditRow = true;
+//       //     // row.isExpanded = false;
+//       //     // if(props.canEditRow) {
+//       //     //   canEditRow = evalFunc(schemaRef.current, props.canEditRow, row.original || {});
+//       //     // }
+//       //     return (
+//       //       <PgIconButton
+//       //         icon={row.isExpanded ? <ArrowDropDownOutlinedIcon fontSize="small" /> : <ArrowRightOutlinedIcon fontSize="small" />}
+//       //         onClick={() => {
+//       //           row.toggleRowExpanded(!row.isExpanded);
+//       //           setRow(row);
+//       //           setSchema(
+//       //             new ActiveQuery({
+//       //               query: row.original.query,
+//       //               backend_type: row.original.backend_type,
+//       //               state_change: row.original.state_change,
+//       //               query_start: row.original.query_start,
+//       //             })
+//       //           );
+//       //         }}
+//       //         disabled={!canEditRow}
+//       //         color="default"
+//       //         aria-label="View the active session details"
+//       //         title={gettext("View the active session details")}
+//       //       />
+//       //     );
+//       //   },
+
+//       //   // Cell: ({row})=>{
+//       //   //   // if(props.canEditRow) {
+//       //   //   //   canEditRow = evalFunc(schemaRef.current, props.canEditRow, row.original || {});
+//       //   //   // }
+//       //   //   return <PgIconButton icon={<PlayArrowIcon />}
+//       //   //   aria-label="Cancel the query"
+//       //   // title={gettext("Cancel the active query")}
+//       //   //   // onClick={()=>{
+//       //   //   //   row.toggleRowExpanded(!row.isExpanded);
+//       //   //   // }}
+//       //   //     onClick={()=>{
+//       //   //       // return (<DataGridView></DataGridView>);
+//       //   //       setCanEdit(!canEdit);
+//       //   //       setRow(row.original);
+//       //   //     }}
+//       //   //   />;
+//       //   // }
+//       // },
+//       {
+//         accessor: 'pid',
+//         Header: gettext('PID'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 60,
+//       },
+//       {
+//         accessor: 'usename',
+//         Header: gettext('User'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 80,
+//       },
+//       {
+//         accessor: 'application_name',
+//         Header: gettext('Application'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 150,
+//       },
+//       {
+//         accessor: 'client_addr',
+//         Header: gettext('Client'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 60,
+//       },
+//       {
+//         accessor: 'backend_start',
+//         Header: gettext('Backend start'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 150,
+//       },
+//       {
+//         accessor: 'state',
+//         Header: gettext('State'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//         minWidth: 26,
+//         maxWidth: 60,
+//       },
+
+//       {
+//         accessor: 'waiting',
+//         Header: gettext('Waiting'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//       },
+//       {
+//         accessor: 'wait_event',
+//         Header: gettext('Wait event'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//       },
+//       {
+//         accessor: 'blocking_pids',
+//         Header: gettext('Blocking PIDs'),
+//         sortble: true,
+//         resizable: false,
+//         disableGlobalFilter: false,
+//       },
+//     ], [schema]
+//   );
+
+//   const activityColumns =  React.useMemo(() => [
+//     {
+//       accessor: 'terminate_query',
+//       Header: ' ',
+//       sortble: true,
+//       resizable: true,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 44,
+
+//       Cell: ({ row }) => {
+//         var terminate_session_url =
+//           url_for('dashboard.index') +
+//           'terminate_session' +
+//           '/' +
+//           sid +
+//           '/' +
+//           did,
+//           title = gettext('Terminate Session?'),
+//           txtConfirm = gettext(
+//             'Are you sure you wish to terminate the session?'
+//           ),
+//           txtSuccess = gettext('Session terminated successfully.'),
+//           txtError = gettext(
+//             'An error occurred whilst terminating the active query.'
+//           ),
+//           action_url = terminate_session_url;
+
+//         const api = getApiInstance();
+
+//         return (
+//           <PgIconButton
+//             variant="outlined"
+//             icon={<CancelIcon fontSize="small" sx={{ color: '#d11616' }} />}
+//             onClick={(e) => {
+//               if (
+//                 !canTakeAction(
+//                   row,
+//                   'terminate',
+//                   nodeData,
+//                   props.treeNodeInfo,
+//                   node
+//                 )
+//               )
+//                 return;
+//               action_url += '/' + row.values.pid;
+//               Notify.confirm(
+//                 title,
+//                 txtConfirm,
+//                 function () {
+//                   api
+//                     .delete(action_url)
+//                     .then(function (res) {
+//                       if (res == gettext('Success')) {
+//                         Notify.success(txtSuccess);
+//                         refresh_grid();
+//                       } else {
+//                         Notify.error(txtError);
+//                       }
+//                     })
+//                     .catch(function (error) {
+//                       Notify.alert(
+//                         gettext('Failed to retrieve data from the server.'),
+//                         gettext(error.message)
+//                       );
+//                     });
+//                 },
+//                 function () {
+//                   return true;
+//                 }
+//               );
+//             }}
+//             color="default"
+//             aria-label="Terminate Session?"
+//             title={gettext('Terminate Session?')}
+//           ></PgIconButton>
+//         );
+//       },
+//     },
+//     {
+//       accessor: 'cancel_Query',
+//       Header: ' ',
+//       sortble: true,
+//       resizable: true,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 44,
+//       Cell: ({ row }) => {
+//         var cancel_query_url =
+//           url_for('dashboard.index') + 'cancel_query' + '/' + sid + '/' + did,
+//           title = gettext('Cancel Active Query?'),
+//           txtConfirm = gettext(
+//             'Are you sure you wish to cancel the active query?'
+//           ),
+//           txtSuccess = gettext('Active query cancelled successfully.'),
+//           txtError = gettext(
+//             'An error occurred whilst cancelling the active query.'
+//           ),
+//           action_url = cancel_query_url;
+//         const api = getApiInstance();
+
+//         return (
+//           <PgIconButton
+//             variant="outlined"
+//             icon={<SquareIcon fontSize="small" />}
+//             onClick={(e) => {
+//               if (
+//                 !canTakeAction(
+//                   row,
+//                   'cancel',
+//                   nodeData,
+//                   props.treeNodeInfo,
+//                   node
+//                 )
+//               )
+//                 return;
+//               action_url += '/' + row.values.pid;
+//               Notify.confirm(
+//                 title,
+//                 txtConfirm,
+//                 function () {
+//                   api
+//                     .delete(action_url)
+//                     .then(function (res) {
+//                       if (res == gettext('Success')) {
+//                         Notify.success(txtSuccess);
+//                         refresh_grid();
+//                       } else {
+//                         Notify.error(txtError);
+//                       }
+//                     })
+//                     .catch(function (error) {
+//                       Notify.alert(
+//                         gettext('Failed to retrieve data from the server.'),
+//                         gettext(error.message)
+//                       );
+//                     });
+//                 },
+//                 function () {
+//                   return true;
+//                 }
+//               );
+//             }}
+//             color="default"
+//             aria-label="Cancel the query"
+//             title={gettext('Cancel the active query')}
+//           ></PgIconButton>
+//         );
+//       },
+//     },
+//     {
+//       accessor: 'view_active_query',
+//       Header: ' ',
+//       sortble: true,
+//       resizable: true,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 44,
+//       Cell: ({ row }) => {
+
+
+//         let canEditRow = true;
+//         return (
+//           <PgIconButton
+//             icon={row.isExpanded ? <ArrowDropDownOutlinedIcon fontSize="small" /> : <ArrowRightOutlinedIcon fontSize="small" />}
+//             onClick={() => {
+//               row.toggleRowExpanded(!row.isExpanded);
+//               setSchema(
+//                 new ActiveQuery({
+//                   query: row.original.query,
+//                   backend_type: row.original.backend_type,
+//                   state_change: row.original.state_change,
+//                   query_start: row.original.query_start,
+//                 })
+//               );
+//             }}
+//             disabled={!canEditRow}
+//             color="default"
+//             aria-label="View the active session details"
+//             title={gettext('View the active session details')}
+//           />
+//         );
+//       },
+
+//       // Cell: ({row})=>{
+//       //   // if(props.canEditRow) {
+//       //   //   canEditRow = evalFunc(schemaRef.current, props.canEditRow, row.original || {});
+//       //   // }
+//       //   return <PgIconButton icon={<PlayArrowIcon />}
+//       //   aria-label="Cancel the query"
+//       // title={gettext("Cancel the active query")}
+//       //   // onClick={()=>{
+//       //   //   row.toggleRowExpanded(!row.isExpanded);
+//       //   // }}
+//       //     onClick={()=>{
+//       //       // return (<DataGridView></DataGridView>);
+//       //       setCanEdit(!canEdit);
+//       //       setRow(row.original);
+//       //     }}
+//       //   />;
+//       // }
+//     },
+//     {
+//       accessor: 'pid',
+//       Header: gettext('PID'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 60,
+//     },
+//     {
+//       accessor: 'usename',
+//       Header: gettext('User'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 80,
+//     },
+//     {
+//       accessor: 'application_name',
+//       Header: gettext('Application'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 150,
+//     },
+//     {
+//       accessor: 'client_addr',
+//       Header: gettext('Client'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 60,
+//     },
+//     {
+//       accessor: 'backend_start',
+//       Header: gettext('Backend start'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 150,
+//     },
+//     {
+//       accessor: 'state',
+//       Header: gettext('State'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 60,
+//     },
+
+//     {
+//       accessor: 'waiting',
+//       Header: gettext('Waiting'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'wait_event',
+//       Header: gettext('Wait event'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'blocking_pids',
+//       Header: gettext('Blocking PIDs'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//   ],[val]);
+
+//   const databaseLocksColumns = React.useMemo(() => [
+//     {
+//       accessor: 'pid',
+//       Header: gettext('PID'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 50,
+//     },
+//     {
+//       accessor: 'locktype',
+//       Header: gettext('Lock type'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 60,
+//     },
+//     {
+//       accessor: 'relation',
+//       Header: gettext('Target relation'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'page',
+//       Header: gettext('Page'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 50,
+//     },
+//     {
+//       accessor: 'tuple',
+//       Header: gettext('Tuple'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 50,
+//     },
+//     {
+//       accessor: 'virtualxid',
+//       Header: gettext('vXID (target)'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'transactionid',
+//       Header: gettext('XID (target)'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'classid',
+//       Header: gettext('Class'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//       minWidth: 26,
+//       maxWidth: 40,
+//     },
+//     {
+//       accessor: 'objid',
+//       Header: gettext('Object ID'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'virtualtransaction',
+//       Header: gettext('vXID (owner)'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'mode',
+//       Header: gettext('Mode'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'granted',
+//       Header: gettext('Granted?'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     // {
+//     //   accessor: "datname",
+//     //   Header: gettext("DB Name?"),
+//     //   sortble: true,
+//     //   resizable: false,
+//     //   disableGlobalFilter: false,
+//     // },
+//     // {
+//     //   accessor: "fastpath",
+//     //   Header: gettext("fastpath?"),
+//     //   sortble: true,
+//     //   resizable: false,
+//     //   disableGlobalFilter: false,
+//     // },
+//     // {
+//     //   accessor: "objsubid",
+//     //   Header: gettext("objsubid?"),
+//     //   sortble: true,
+//     //   resizable: false,
+//     //   disableGlobalFilter: false,
+//     // },
+//   ]);
+
+//   const databasePreparedColumns = React.useMemo(() => [
+//     {
+//       accessor: 'git',
+//       Header: gettext('Name'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'Owner',
+//       Header: gettext('Owner'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'transaction',
+//       Header: gettext('XID'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//     {
+//       accessor: 'prepared',
+//       Header: gettext('Prepared at'),
+//       sortble: true,
+//       resizable: false,
+//       disableGlobalFilter: false,
+//     },
+//   ]);
+
+//   let chartsDomObj = null;
+
+//   // const memoizedValue = useMemo(() => {}true, [nodeData]);
+
+//   const canTakeAction = (row, cellAction, nodeData, treeNodeInfo, node) => {
+//     // We will validate if user is allowed to cancel the active query
+//     // If there is only one active session means it probably our main
+//     // connection session
+//     console.log(row, '===>', nodeData, treeNodeInfo, node.collection);
+//     // m.collection.where({
+//     //   'state': 'active',
+//     // }),
+//     var pg_version = nodeData.version || null,
+//       cellAction = cellAction || null,
+//       is_cancel_session = cellAction === 'cancel',
+//       txtMessage,
+//       maintenance_database = treeNodeInfo.server.db,
+//       is_super_user,
+//       current_user;
+
+//     var can_signal_backend =
+//       treeNodeInfo.server && treeNodeInfo.server.user
+//         ? treeNodeInfo.server.user.can_signal_backend
+//         : false;
+
+//     if (
+//       treeNodeInfo.server &&
+//       treeNodeInfo.server.user &&
+//       treeNodeInfo.server.user.is_superuser
+//     ) {
+//       is_super_user = true;
+//     } else {
+//       is_super_user = false;
+//       current_user =
+//         treeNodeInfo.server && treeNodeInfo.server.user
+//           ? treeNodeInfo.server.user.name
+//           : null;
+//     }
+
+//     // With PG10, We have background process showing on dashboard
+//     // We will not allow user to cancel them as they will fail with error
+//     // anyway, so better usability we will throw our on notification
+
+//     // Background processes do not have database field populated
+//     if (pg_version && pg_version >= 100000 && !row.original.datname) {
+//       if (is_cancel_session) {
+//         txtMessage = gettext('You cannot cancel background worker processes.');
+//       } else {
+//         txtMessage = gettext(
+//           'You cannot terminate background worker processes.'
+//         );
+//       }
+//       Notify.info(txtMessage);
+//       return false;
+//       // If it is the last active connection on maintenance db then error out
+//     } else if (
+//       maintenance_database == row.original.datname &&
+//       row.original.state == 'active'
+//     ) {
+//       if (is_cancel_session) {
+//         txtMessage = gettext(
+//           'You are not allowed to cancel the main active session.'
+//         );
+//       } else {
+//         txtMessage = gettext(
+//           'You are not allowed to terminate the main active session.'
+//         );
+//       }
+//       Notify.error(txtMessage);
+//       return false;
+//     } else if (is_cancel_session && row.original.state == 'idle') {
+//       // If this session is already idle then do nothing
+//       Notify.info(gettext('The session is already in idle state.'));
+//       return false;
+//     } else if (can_signal_backend) {
+//       // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
+//       return true;
+//     } else if (is_super_user) {
+//       // Super user can do anything
+//       return true;
+//     } else if (current_user && current_user == m.get('usename')) {
+//       // Non-super user can cancel only their active queries
+//       return true;
+//     } else {
+//       // Do not allow to cancel someone else session to non-super user
+//       if (is_cancel_session) {
+//         txtMessage = gettext(
+//           'Superuser privileges are required to cancel another users query.'
+//         );
+//       } else {
+//         txtMessage = gettext(
+//           'Superuser privileges are required to terminate another users query.'
+//         );
+//       }
+//       Notify.error(txtMessage);
+//       return false;
+//     }
+//   };
+
+//   useEffect(() => {
+//     let url,
+//       message = gettext(
+//         'Please connect to the selected server to view the dashboard.'
+//       );
+
+//     if (sid && props.serverConnected) {
+//       let columns = activityColumns;
+//       if (val === 0) {
+//         url = url_for('dashboard.activity');
+//       } else if (val === 1) {
+//         url = url_for('dashboard.locks');
+//         columns = databaseLocksColumns;
+//       } else if (val === 2) {
+//         url = url_for('dashboard.prepared');
+//         columns = databasePreparedColumns;
+//       } else {
+//         url = url_for('dashboard.config');
+//         columns = serverConfigColumns;
+//       }
+
+//       message = gettext('No statistics are available for the selected object.');
+//       if (did) url += sid + '/' + did;
+//       else url += sid;
+
+//       const api = getApiInstance();
+//       if (true) {
+//         api({
+//           url: url,
+//           type: 'GET',
+//         })
+//           .then((res) => {
+//             // parseData(res.data, activityColumns);
+//             setdashData(parseData(res.data, columns, sid, did));
+//           })
+//           .catch((e) => {
+//             Notify.alert(
+//               gettext('Failed to retrieve data from the server.'),
+//               gettext(e.message)
+//             );
+//             // show failed message.
+//             setMsg(gettext('Failed to retrieve data from the server.'));
+//           });
+//       } else {
+//         setMsg(message);
+//       }
+//     }
+//     if (message != '') {
+//       setMsg(message);
+//     }
+//   }, [nodeData, val, did]);
+
+//   // useEffect(() => {
+//   //   if (nodeData && nodeData._type) {
+//   //     var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item);
+//   //     // url = NodesDashboard.url(nodeData, item, treeHierarchy);
+//   //     let url = url_for("dashboard.index"),
+//   //       dashboardActivityUrl = url_for("dashboard.activity"),
+//   //       dashboardLockURL = url_for("dashboard.locks"),
+//   //       dashboardPrepared = url_for("dashboard.prepared");
+
+//   //     console.log(dashboardActivityUrl, dashboardLockURL, dashboardPrepared);
+
+//   //     if (true) {
+//   //       var dashboardVisible = true,
+//   //         cancel_query_url = "",
+//   //         terminate_session_url = "",
+//   //         is_super_user = false,
+//   //         current_user,
+//   //         maintenance_database,
+//   //         is_server_dashboard = false,
+//   //         is_database_dashboard = false,
+//   //         can_signal_backend = false;
+//   //       self.version =
+//   //         (treeHierarchy.server && treeHierarchy.server.version) || 0;
+
+//   // cancel_query_url = url + "cancel_query/";
+//   // terminate_session_url = url + "terminate_session/";
+
+//   //       // Check if user is super user
+//   //       var server = treeHierarchy["server"];
+//   //       maintenance_database = (server && server.db) || null;
+//   //       can_signal_backend =
+//   //         server && server.user ? server.user.can_signal_backend : false;
+
+//   //       if (server && server.user && server.user.is_superuser) {
+//   //         is_super_user = true;
+//   //       } else {
+//   //         is_super_user = false;
+//   //         // Set current user
+//   //         current_user = server && server.user ? server.user.name : null;
+//   //       }
+
+//   //       if ("database" in treeHierarchy) {
+//   //         self.sid = treeHierarchy.server._id;
+//   //         self.did = treeHierarchy.database._id;
+//   //         is_server_dashboard = false;
+//   //         is_database_dashboard = true;
+//   //         url += self.sid + "/" + self.did;
+//   //         cancel_query_url += self.sid + "/" + self.did + "/";
+//   //         terminate_session_url += self.sid + "/" + self.did + "/";
+//   //       } else if ("server" in treeHierarchy) {
+//   //         self.sid = treeHierarchy.server._id;
+//   //         self.did = -1;
+//   //         is_server_dashboard = true;
+//   //         is_database_dashboard = false;
+//   //         url += self.sid;
+//   //         cancel_query_url += self.sid + "/";
+//   //         terminate_session_url += self.sid + "/";
+//   //       } else {
+//   //         is_server_dashboard = is_database_dashboard = false;
+//   //       }
+//   //     } else {
+//   //       is_server_dashboard = is_database_dashboard = false;
+//   //     }
+
+//   //     var dashboardPanel = pgBrowser.panels["dashboard"].panel;
+//   //     if (dashboardPanel) {
+//   //       var div = dashboardPanel.layout().scene().find(".pg-panel-content");
+
+//   //       if (div) {
+//   //         if (nodeData.connected || _.isUndefined(nodeData.connected)) {
+//   //           // Avoid unnecessary reloads
+//   //           if (
+//   //             url !== $(dashboardPanel).data("dashboard_url") ||
+//   //             (url === $(dashboardPanel).data("dashboard_url") &&
+//   //               $(dashboardPanel).data("server_status") == false)
+//   //           ) {
+//   //             chartsDomObj && chartsDomObj.unmount();
+//   //             const api = getApiInstance();
+//   //             // $(div).empty();
+//   //             console.log(url);
+
+//   //             api({
+//   //               url: url,
+//   //               type: "GET",
+//   //               dataType: "html",
+//   //             })
+//   //               .then(function (data) {
+//   //                 console.log("data", data.data);
+//   //                 // $(div).html(data);
+//   //                 setdashData(data.data);
+
+//   //                 // self.init_dashboard();
+//   //               })
+//   //               .catch(function (e) {
+//   //                 Notify.alert(
+//   //                   gettext("Failed to retrieve data from the server."),
+//   //                   gettext(e.message)
+//   //                 );
+//   //                 // show failed message.
+//   //                 setMsg(gettext("Failed to retrieve data from the server."));
+//   //               });
+//   //           }
+//   //           // $(div).html(
+//   //           //   '<div class="pg-panel-message" role="alert">' +
+//   //           //     gettext("Loading dashboard...") +
+//   //           //     "</div>"
+//   //           // );
+//   //           //   // ajaxHook();
+//   //           // $(dashboardPanel).data("server_status", true);
+//   //         }
+//   //       } else {
+//   //         chartsDomObj && chartsDomObj.unmount();
+//   //         $(div).html(
+//   //           '<div class="pg-panel-message" role="alert">' +
+//   //             gettext(
+//   //               "Please connect to the selected server to view the dashboard."
+//   //             ) +
+//   //             "</div>"
+//   //         );
+//   //         $(dashboardPanel).data("server_status", false);
+//   //       }
+//   //       // Cache the current IDs for next time
+//   //       $(dashboardPanel).data("dashboard_url", url);
+//   //     }
+//   //   }
+//   // });
+
+//   return (
+//     <>
+//       {sid && props.serverConnected ? (
+//         <Box className={classes.emptyPanel}>
+//           <Graphs
+//             preferences={preferences}
+//             sid={sid}
+//             did={did}
+//             pageVisible={true}
+//           ></Graphs>
+//           <Box className={classes.tableCell}>
+//             <Box className="card-header" title={gettext('Server activity')}>
+//               {gettext('Server activity')}{' '}
+//             </Box>
+//             {/* <Box className={classes.tableCell}> */}
+//             <Tabs
+//               value={val}
+//               onChange={tabChanged}
+//               className={classes.searchInput}
+//             >
+//               {tab.map((tabValue, i) => {
+//                 return <Tab key={tabValue} label={tabValue} />;
+//               })}
+//             </Tabs>
+//             {/* </Box> */}
+//             {/* <Box className={classes.component}> */}
+//             <PgTable
+//               // className={classes.autoResizer}searchText={searchVal}
+//               // type={"panel"}
+//               // className={classes.autoResizer}
+//               className={classes.table}
+//               accessPath={[editRow.id]}
+//               columns={
+//                 val === 0
+//                   ? activityColumns
+//                   : val === 1
+//                     ? databaseLocksColumns
+//                     : val == 2
+//                       ? databasePreparedColumns
+//                       : serverConfigColumns
+//               }
+//               data={dashData}
+//               // canEdit={canEdit}
+//               schema={schema}
+//               // rowD={editRow}
+//             ></PgTable>
+//             {/* </Box> */}
+//           </Box>
+//         </Box>
+//       ) : sid && !props.serverConnected ? (
+//         <div className={classes.emptyPanel}>
+//           <div className={classes.panelIcon}>
+//             <i className="fa fa-exclamation-circle"></i>
+//             <span className={classes.panelMessage}>{gettext(msg)}</span>
+//           </div>
+//         </div>
+//       ) : (
+//         <WelcomeDashboard
+//           pgBrowser={pgBrowser}
+//           node={node}
+//           itemData={nodeData}
+//           item={item}
+//           sid={sid}
+//           did={did}
+//         />
+//       )}
+//     </>
+//   );
+// }
+
+
+// export function ChartContainer(props) {
+//   return (
+//     <div className="card dashboard-graph" role="object-document" tabIndex="0" aria-labelledby={props.id}>
+//       <div className="card-header">
+//         <div className="d-flex">
+//           <div id={props.id}>{props.title}</div>
+//           <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
+//         </div>
+//       </div>
+//       <div className="card-body dashboard-graph-body">
+//         <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none': '')}>
+//           {props.children}
+//         </div>
+//         <ChartError message={props.errorMsg} />
+//       </div>
+//     </div>
+//   );
+// }
+
+// ChartContainer.propTypes = {
+//   id: PropTypes.string.isRequired,
+//   title: PropTypes.string.isRequired,
+//   legendRef: PropTypes.oneOfType([
+//     PropTypes.func,
+//     PropTypes.shape({ current: PropTypes.any }),
+//   ]).isRequired,
+//   children: PropTypes.node.isRequired,
+//   errorMsg: PropTypes.string,
+// };
+
+// export function ChartError(props) {
+//   if(props.message === null) {
+//     return  <></>;
+//   }
+//   return (
+//     <div className="pg-panel-error pg-panel-message" role="alert">{props.message}</div>
+//   );
+// }
+
+// ChartError.propTypes = {
+//   message: PropTypes.string,
+// };
+
+// export function DashboardRow({children}) {
+//   return (
+//     <div className="row dashboard-row">{children}</div>
+//   );
+// }
+// DashboardRow.propTypes = {
+//   children: PropTypes.node.isRequired,
+// };
+
+// export function DashboardRowCol({breakpoint, parts, children}) {
+//   return (
+//     <div className={`col-${breakpoint}-${parts}`}>{children}</div>
+//   );
+// }
+
+// DashboardRowCol.propTypes = {
+//   breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
+//   parts: PropTypes.number.isRequired,
+//   children: PropTypes.node.isRequired,
+// };
diff --git a/web/pgadmin/dashboard/static/js/dashboard_components.jsx b/web/pgadmin/dashboard/static/js/dashboard_components.jsx
deleted file mode 100644
index a723dd242..000000000
--- a/web/pgadmin/dashboard/static/js/dashboard_components.jsx
+++ /dev/null
@@ -1,74 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export function ChartContainer(props) {
-  return (
-    <div className="card dashboard-graph" role="object-document" tabIndex="0" aria-labelledby={props.id}>
-      <div className="card-header">
-        <div className="d-flex">
-          <div id={props.id}>{props.title}</div>
-          <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
-        </div>
-      </div>
-      <div className="card-body dashboard-graph-body">
-        <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none': '')}>
-          {props.children}
-        </div>
-        <ChartError message={props.errorMsg} />
-      </div>
-    </div>
-  );
-}
-
-ChartContainer.propTypes = {
-  id: PropTypes.string.isRequired,
-  title: PropTypes.string.isRequired,
-  legendRef: PropTypes.oneOfType([
-    PropTypes.func,
-    PropTypes.shape({ current: PropTypes.any }),
-  ]).isRequired,
-  children: PropTypes.node.isRequired,
-  errorMsg: PropTypes.string,
-};
-
-export function ChartError(props) {
-  if(props.message === null) {
-    return  <></>;
-  }
-  return (
-    <div className="pg-panel-error pg-panel-message" role="alert">{props.message}</div>
-  );
-}
-
-ChartError.propTypes = {
-  message: PropTypes.string,
-};
-
-export function DashboardRow({children}) {
-  return (
-    <div className="row dashboard-row">{children}</div>
-  );
-}
-DashboardRow.propTypes = {
-  children: PropTypes.node.isRequired,
-};
-
-export function DashboardRowCol({breakpoint, parts, children}) {
-  return (
-    <div className={`col-${breakpoint}-${parts}`}>{children}</div>
-  );
-}
-
-DashboardRowCol.propTypes = {
-  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
-  parts: PropTypes.number.isRequired,
-  children: PropTypes.node.isRequired,
-};
diff --git a/web/pgadmin/dashboard/static/js/dashboard_ponents.jsx b/web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
new file mode 100644
index 000000000..3d4237901
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
@@ -0,0 +1,74 @@
+// /////////////////////////////////////////////////////////////
+// //
+// // pgAdmin 4 - PostgreSQL Tools
+// //
+// // Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// // This software is released under the PostgreSQL Licence
+// //
+// //////////////////////////////////////////////////////////////
+// import React from 'react';
+// import PropTypes from 'prop-types';
+
+// export function ChartContainer(props) {
+//   return (
+//     <div className="card dashboard-graph" role="object-document" tabIndex="0" aria-labelledby={props.id}>
+//       <div className="card-header">
+//         <div className="d-flex">
+//           <div id={props.id}>{props.title}</div>
+//           <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
+//         </div>
+//       </div>
+//       <div className="card-body dashboard-graph-body">
+//         <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none': '')}>
+//           {props.children}
+//         </div>
+//         <ChartError message={props.errorMsg} />
+//       </div>
+//     </div>
+//   );
+// }
+
+// ChartContainer.propTypes = {
+//   id: PropTypes.string.isRequired,
+//   title: PropTypes.string.isRequired,
+//   legendRef: PropTypes.oneOfType([
+//     PropTypes.func,
+//     PropTypes.shape({ current: PropTypes.any }),
+//   ]).isRequired,
+//   children: PropTypes.node.isRequired,
+//   errorMsg: PropTypes.string,
+// };
+
+// export function ChartError(props) {
+//   if(props.message === null) {
+//     return  <></>;
+//   }
+//   return (
+//     <div className="pg-panel-error pg-panel-message" role="alert">{props.message}</div>
+//   );
+// }
+
+// ChartError.propTypes = {
+//   message: PropTypes.string,
+// };
+
+// export function DashboardRow({children}) {
+//   return (
+//     <div className="row dashboard-row">{children}</div>
+//   );
+// }
+// DashboardRow.propTypes = {
+//   children: PropTypes.node.isRequired,
+// };
+
+// export function DashboardRowCol({breakpoint, parts, children}) {
+//   return (
+//     <div className={`col-${breakpoint}-${parts}`}>{children}</div>
+//   );
+// }
+
+// DashboardRowCol.propTypes = {
+//   breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
+//   parts: PropTypes.number.isRequired,
+//   children: PropTypes.node.isRequired,
+// };
diff --git a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html
deleted file mode 100644
index 148ce96ab..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<div class="container-fluid dashboard-container negative-space">
-    <div id="dashboard-graphs"></div>
-    <div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
-        <div class="card-header">
-            <span id="dashboard-activity-header">{{ _('Server activity') }}</span>
-        </div>
-        <div class="card-body">
-            <div class="row">
-                <div class="col-md-9 col-12 pr-0">
-                    <ul class="nav nav-tabs" role="tablist" aria-labelledby="dashboard-activity-header">
-                        <li class="nav-item">
-                            <a class="nav-link active show" id="tab_panel_database_activity_tab" href="#tab_panel_database_activity" aria-controls="tab_database_activity"
-                                role="tab" data-toggle="tab">{{ _('Sessions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_database_locks_tab" href="#tab_panel_database_locks" aria-controls="tab_database_locks"
-                               role="tab" data-toggle="tab">{{ _('Locks') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_database_prepared_tab" href="#tab_panel_database_prepared" aria-controls="tab_database_prepared"
-                               role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
-                        </li>
-                    </ul>
-                </div>
-                <div class="col-md-3 col-12 pl-0 text-right">
-                    <div class="navtab-inline-controls">
-                        <div class="input-group">
-                            <div class="input-group-prepend">
-                                <span class="input-group-text fa fa-search" id="labelSearch" aria-label="{{ _('Search') }}"></span>
-                            </div>
-                            <input type="search" class="form-control" id="txtGridSearch" placeholder="{{ _('Search') }}" aria-describedby="labelSearch" aria-labelledby="labelSearch">
-                        </div>
-                        <button id="btn_refresh" type="button" class="btn btn-primary-icon btn-navtab-inline" title="{{ _('Refresh') }}" aria-label="{{ _('Refresh') }}">
-                            <span class="fa fa-sync-alt" aria-hidden="true"></span>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <!-- Nav tabs -->
-
-
-            <!-- Tab panes -->
-            <div class="tab-content">
-                <div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_database_activity" aria-labelledby="tab_panel_database_activity_tab">
-                    <div id="database_activity" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_locks" aria-labelledby="tab_panel_database_locks_tab">
-                    <div id="database_locks" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_prepared" aria-labelledby="tab_panel_database_prepared_tab">
-                    <div id="database_prepared" class="grid-container"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
-        {{ _('All Dashboard elements are currently disabled.') }}
-    </div>
-</div>
diff --git a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html
deleted file mode 100644
index 874a1e206..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<div class="container-fluid dashboard-container negative-space">
-    <div id="dashboard-graphs">
-    </div>
-    <div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
-        <div class="card-header">
-            <span id="server-activity-header">{{ _('Server activity') }}</span>
-        </div>
-        <div class="card-body">
-            <div class="row">
-                <div class="col-md-9 col-12 pr-0">
-                    <ul class="nav nav-tabs" role="tablist" aria-labelledby="server-activity-header">
-                        <li class="nav-item">
-                            <a class="nav-link active show" id="tab_panel_server_activity_tab" href="#tab_panel_server_activity" aria-controls="tab_server_activity"
-                                role="tab" data-toggle="tab">{{_('Sessions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_locks_tab" href="#tab_panel_server_locks" aria-controls="tab_server_locks"
-                                role="tab" data-toggle="tab">{{ _('Locks') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_prepared_tab" href="#tab_panel_server_prepared" aria-controls="tab_server_prepared"
-                                role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_config_tab" href="#tab_panel_server_config" aria-controls="tab_server_config"
-                                role="tab" data-toggle="tab">{{ _('Configuration') }}</a>
-                        </li>
-                    </ul>
-                </div>
-                <div class="col-md-3 col-12 pl-0 text-right">
-                    <div class="navtab-inline-controls">
-                        <div class="input-group">
-                            <div class="input-group-prepend">
-                                <span class="input-group-text fa fa-search" id="labelSearch"></span>
-                            </div>
-                            <input type="search" class="form-control" id="txtGridSearch" placeholder="{{ _('Search') }}" aria-label="{{ _('Search') }}" aria-describedby="labelSearch">
-                        </div>
-                        <button id="btn_refresh" type="button" class="btn btn-primary-icon btn-navtab-inline" title="{{ _('Refresh') }}" aria-label="{{ _('Refresh') }}">
-                            <span class="fa fa-sync-alt" aria-hidden="true"></span>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <!-- Nav tabs -->
-
-
-            <!-- Tab panes -->
-            <div class="tab-content">
-                <div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_server_activity" aria-labelledby="tab_panel_server_activity_tab">
-                    <div id="server_activity" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_locks" aria-labelledby="tab_panel_server_locks_tab">
-                    <div id="server_locks" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_prepared" aria-labelledby="tab_panel_server_prepared_tab">
-                    <div id="server_prepared" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_config" aria-labelledby="tab_panel_server_config_tab">
-                    <div id="server_config" class="grid-container"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
-        {{ _('All Dashboard elements are currently disabled.') }}
-    </div>
-</div>
diff --git a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html
deleted file mode 100644
index fc798ab19..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<div class="container-fluid negative-space">
-    <div class="dashboard-container">
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card">
-                    <div class="card-header">{{ _('Welcome') }}</div>
-                    <div class="card-body p-2">
-                        <div class="welcome-logo" aria-hidden="true">
-                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 130">
-                               <defs>
-                                  <style>.cls-1{stroke:#000;stroke-width:10.19px;}.cls-2{fill:#336791;}.cls-3,.cls-4,.cls-9{fill:none;}.cls-3,.cls-4,.cls-5,.cls-6{stroke:#fff;}.cls-3,.cls-4{stroke-linecap:round;stroke-width:3.4px;}.cls-3{stroke-linejoin:round;}.cls-4{stroke-linejoin:bevel;}.cls-5,.cls-6{fill:#fff;}.cls-5{stroke-width:1.13px;}.cls-6{stroke-width:0.57px;}.cls-7{fill:#2775b6;}.cls-8{fill:#333;}.cls-9{stroke:#333;stroke-width:3px;}</style>
-                               </defs>
-                               <title>pgAdmin_PostgreSQL</title>
-                               <g id="Layer_1" data-name="Layer 1">
-                                  <g id="Layer_3">
-                                     <path class="cls-1" d="M95.59,93.65c.77-6.44.54-7.38,5.33-6.34l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21a9,9,0,0,0,.1,2.46c-3.7,4.13-2.62,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.46,1.16,1.36,8.35,1.56,13.48s.55,9.93,1.6,12.75,2.28,10.1,12,8C88.81,119.46,95,117,95.59,93.65" />
-                                     <path class="cls-2" d="M117.17,79.2c-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21A9.41,9.41,0,0,0,59,80.22c-3.7,4.13-2.61,4.86-10,6.38s-3.08,4.29-.21,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.45,1.16,2.47,7.56,2.3,13.35s-.28,9.77.86,12.88,2.28,10.1,12,8C88.81,119.46,93,115,93.6,107.42,94,102.07,95,102.87,95,98.08l.75-2.26c.87-7.26.14-9.6,5.15-8.51l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31Z" />
-                                     <path class="cls-3" d="M66.33,83.36c-.38,13.5.09,27.09,1.41,30.39s4.15,9.73,13.88,7.64c8.12-1.74,11.08-5.11,12.36-12.55.94-5.47,2.77-20.67,3-23.79" />
-                                     <path class="cls-3" d="M54.67,15.7s-44-18-42,22.93c.44,8.7,12.48,65.87,26.84,48.6,5.25-6.32,10-11.27,10-11.27" />
-                                     <path class="cls-3" d="M78.45,12.42c-1.52.47,24.49-9.51,39.28,9.38,5.22,6.67-.83,33.94-15.31,55.42" />
-                                     <path class="cls-4" d="M102.42,77.22s.94,4.64,14.65,1.81c6-1.24,2.4,3.48-3.7,6.31-5,2.32-16.21,2.92-16.39-.29-.47-8.27,5.9-5.76,5.44-7.83-.42-1.87-3.26-3.7-5.15-8.27-1.64-4-22.57-34.58,5.8-30,1-.22-7.4-27-33.95-27.42S43.45,44.14,43.45,44.14" />
-                                     <path class="cls-3" d="M58.9,80.05c-3.7,4.13-2.61,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52,1.66-2.32,0-6-2.28-7-1.1-.46-2.57-1-4.46,1.09Z" />
-                                     <path class="cls-3" d="M58.66,80c-.38-2.44.79-5.33,2.05-8.71C62.6,66.19,67,61.11,63.47,45c-2.6-12-20-2.5-20-.87a81.48,81.48,0,0,1-.29,16c-1.41,10.06,6.4,18.57,15.39,17.7" />
-                                     <path class="cls-5" d="M54.51,43.9c-.08.55,1,2,2.45,2.23a2.62,2.62,0,0,0,2.72-1.51c.08-.56-1-1.17-2.44-1.37s-2.65.09-2.73.65Z" />
-                                     <path class="cls-6" d="M98,42.76c.07.56-1,2-2.45,2.24a2.64,2.64,0,0,1-2.73-1.52c-.07-.55,1-1.16,2.45-1.36s2.65.09,2.73.64Z" />
-                                     <path class="cls-3" d="M103.07,38.92c.24,4.36-.94,7.33-1.08,12-.22,6.74,3.21,14.46-2,22.19" />
-                                  </g>
-                                  <path class="cls-7 app-name" d="M154.72,28.15h5.16v4.16A12.84,12.84,0,0,1,163.35,29a11.17,11.17,0,0,1,6.28-1.76,11.84,11.84,0,0,1,9.08,4.09c2.48,2.72,3.73,6.62,3.73,11.67q0,10.26-5.38,14.65a12.2,12.2,0,0,1-7.95,2.79,10.78,10.78,0,0,1-6-1.56,13.55,13.55,0,0,1-3.14-3v16h-5.28Zm19.84,24.6Q177,49.65,177,43.5a17,17,0,0,0-1.09-6.44,7.51,7.51,0,0,0-7.53-5.19q-5.49,0-7.52,5.48a21.49,21.49,0,0,0-1.09,7.44A15.64,15.64,0,0,0,160.88,51a8,8,0,0,0,13.68,1.78Z" />
-                                  <path class="cls-7 app-name" d="M206,29.26a14.6,14.6,0,0,1,3,3V28.3h4.86V56.83c0,4-.58,7.13-1.75,9.44q-3.27,6.38-12.35,6.38a15.07,15.07,0,0,1-8.5-2.27,8.86,8.86,0,0,1-3.85-7.1h5.36a6,6,0,0,0,1.52,3.25q1.77,1.75,5.59,1.76,6,0,7.9-4.28,1.1-2.52,1-9a10.39,10.39,0,0,1-3.8,3.57,13.56,13.56,0,0,1-14.75-2.45q-3.81-3.62-3.81-12,0-7.89,3.84-12.31a11.85,11.85,0,0,1,9.27-4.42A11.37,11.37,0,0,1,206,29.26Zm.64,5.66a7.61,7.61,0,0,0-6.09-2.81A7.52,7.52,0,0,0,193,37.32a20.56,20.56,0,0,0-1.08,7.3c0,3.53.72,6.22,2.14,8.07a6.93,6.93,0,0,0,5.76,2.77,8.09,8.09,0,0,0,8-5.13A16.72,16.72,0,0,0,209,43.56Q209,37.73,206.62,34.92Z" />
-                                  <path class="cls-7 app-name" d="M235.16,16.34h6.58l15.62,43H251l-4.5-12.89H229.6l-4.67,12.89h-6Zm9.67,25.4-6.63-19-6.88,19Z" />
-                                  <path class="cls-7 app-name" d="M279.16,29a14.3,14.3,0,0,1,3.18,3.08V16.2h5.07V59.38h-4.75V55a11.33,11.33,0,0,1-4.35,4.19,12.51,12.51,0,0,1-5.75,1.28,11.61,11.61,0,0,1-9-4.4q-3.82-4.41-3.83-11.74a20.35,20.35,0,0,1,3.49-11.88,11.41,11.41,0,0,1,10-5A11.15,11.15,0,0,1,279.16,29ZM267.39,52.5q2.13,3.39,6.82,3.39a7.17,7.17,0,0,0,6-3.14c1.56-2.1,2.35-5.12,2.35-9s-.81-6.9-2.42-8.81a7.56,7.56,0,0,0-6-2.85,7.88,7.88,0,0,0-6.43,3c-1.64,2-2.46,5-2.46,9A15.62,15.62,0,0,0,267.39,52.5Z" />
-                                  <path class="cls-7 app-name" d="M295.29,28h5.21v4.46a17.4,17.4,0,0,1,3.4-3.37,10.24,10.24,0,0,1,5.92-1.79,9.34,9.34,0,0,1,6,1.85,9.61,9.61,0,0,1,2.34,3.1,11.37,11.37,0,0,1,4.13-3.73,11.52,11.52,0,0,1,5.33-1.22q6.33,0,8.62,4.57a15,15,0,0,1,1.23,6.62V59.38H332V37.58c0-2.09-.52-3.52-1.57-4.3a6.2,6.2,0,0,0-3.82-1.17,7.58,7.58,0,0,0-5.35,2.08c-1.49,1.38-2.24,3.7-2.24,6.94V59.38h-5.36V38.9a10.78,10.78,0,0,0-.76-4.66q-1.2-2.19-4.49-2.19A7.73,7.73,0,0,0,303,34.36c-1.63,1.54-2.45,4.34-2.45,8.38V59.38h-5.27Z" />
-                                  <path class="cls-7 app-name" d="M345.27,16.34h5.36v6h-5.36Zm0,11.81h5.36V59.38h-5.36Z" />
-                                  <path class="cls-7 app-name" d="M358.6,28h5v4.46a14,14,0,0,1,4.72-4,12.56,12.56,0,0,1,5.53-1.2c4.46,0,7.46,1.55,9,4.66a16.52,16.52,0,0,1,1.29,7.29V59.38h-5.37V39.61A10.8,10.8,0,0,0,378,35a5.15,5.15,0,0,0-5.1-2.93,10.21,10.21,0,0,0-3.08.38A8,8,0,0,0,366,35a7.66,7.66,0,0,0-1.71,3.2,21.84,21.84,0,0,0-.4,4.74V59.38H358.6Z" />
-                                  <path class="cls-8 app-tagline" d="M155.24,86.87h3.9l5.77,17,5.74-17h3.87V107h-2.6V95.1q0-.61,0-2c0-.94,0-2,0-3L166.24,107h-2.7L157.75,90v.61c0,.49,0,1.24,0,2.25s.05,1.75.05,2.22V107h-2.6Z" />
-                                  <path class="cls-8 app-tagline" d="M186.15,98.09a1.35,1.35,0,0,0,1.14-.71,2.31,2.31,0,0,0,.16-.94,2,2,0,0,0-.89-1.84A4.79,4.79,0,0,0,184,94a3.21,3.21,0,0,0-2.73,1,3.44,3.44,0,0,0-.59,1.72h-2.3A4.28,4.28,0,0,1,180.14,93,7.16,7.16,0,0,1,184.05,92a8,8,0,0,1,4.19,1,3.34,3.34,0,0,1,1.6,3.06v8.44a1.06,1.06,0,0,0,.16.62.77.77,0,0,0,.66.23l.37,0,.44-.07V107a7.38,7.38,0,0,1-.88.21,5.92,5.92,0,0,1-.82,0,2,2,0,0,1-1.84-.9,3.63,3.63,0,0,1-.43-1.36,6.16,6.16,0,0,1-2.16,1.71,6.56,6.56,0,0,1-3.1.73,4.59,4.59,0,0,1-3.33-1.24,4.09,4.09,0,0,1-1.29-3.09,4,4,0,0,1,1.27-3.16,6.16,6.16,0,0,1,3.34-1.38ZM181,104.74a2.88,2.88,0,0,0,1.84.62,5.51,5.51,0,0,0,2.52-.61,3.37,3.37,0,0,0,2-3.26v-2a3.79,3.79,0,0,1-1.16.48,10.37,10.37,0,0,1-1.39.28l-1.49.19a5.68,5.68,0,0,0-2,.56,2.18,2.18,0,0,0-1.14,2A2,2,0,0,0,181,104.74Z" />
-                                  <path class="cls-8 app-tagline" d="M193.88,92.31h2.33v2.08a6.73,6.73,0,0,1,2.2-1.85A6,6,0,0,1,201,92q3.12,0,4.21,2.18a7.73,7.73,0,0,1,.6,3.4V107h-2.5V97.73a4.87,4.87,0,0,0-.4-2.16,2.41,2.41,0,0,0-2.38-1.37,4.75,4.75,0,0,0-1.43.18,3.68,3.68,0,0,0-1.78,1.2,3.55,3.55,0,0,0-.8,1.5,10.3,10.3,0,0,0-.18,2.21V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M217.29,98.09a1.33,1.33,0,0,0,1.14-.71,2.15,2.15,0,0,0,.16-.94,2,2,0,0,0-.89-1.84,4.79,4.79,0,0,0-2.56-.56,3.24,3.24,0,0,0-2.73,1,3.44,3.44,0,0,0-.58,1.72h-2.3A4.27,4.27,0,0,1,211.28,93,7.19,7.19,0,0,1,215.2,92a8,8,0,0,1,4.19,1A3.36,3.36,0,0,1,221,96v8.44a1.14,1.14,0,0,0,.15.62.79.79,0,0,0,.67.23l.37,0,.43-.07V107a7.32,7.32,0,0,1-.87.21,6,6,0,0,1-.82,0,2,2,0,0,1-1.85-.9,3.46,3.46,0,0,1-.42-1.36,6.16,6.16,0,0,1-2.16,1.71,6.63,6.63,0,0,1-3.11.73,4.58,4.58,0,0,1-3.32-1.24,4.06,4.06,0,0,1-1.3-3.09A4,4,0,0,1,210,100a6.13,6.13,0,0,1,3.33-1.38Zm-5.18,6.65a2.91,2.91,0,0,0,1.85.62,5.47,5.47,0,0,0,2.51-.61,3.38,3.38,0,0,0,2.06-3.26v-2a3.9,3.9,0,0,1-1.16.48,10.51,10.51,0,0,1-1.4.28l-1.48.19a5.55,5.55,0,0,0-2,.56,2.17,2.17,0,0,0-1.15,2A2,2,0,0,0,212.11,104.74Z" />
-                                  <path class="cls-8 app-tagline" d="M233.16,92.9a7.05,7.05,0,0,1,1.42,1.39V92.45h2.27v13.32a10,10,0,0,1-.82,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.15,4.15,0,0,1-1.8-3.32H227a2.81,2.81,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.88,0,3.1-.66,3.68-2a11.15,11.15,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,5.93,5.93,0,0,1-2.74.54,5.79,5.79,0,0,1-4.14-1.69q-1.79-1.68-1.78-5.58a8.49,8.49,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.33,5.33,0,0,1,233.16,92.9Zm.3,2.64a3.77,3.77,0,0,0-6.38,1.12,9.73,9.73,0,0,0-.5,3.4,6.05,6.05,0,0,0,1,3.77,3.21,3.21,0,0,0,2.68,1.29,3.77,3.77,0,0,0,3.72-2.39,7.71,7.71,0,0,0,.6-3.16A6.13,6.13,0,0,0,233.46,95.54Z" />
-                                  <path class="cls-8 app-tagline" d="M249.64,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,17.44,17.44,0,0,1,.22,3.23H242.4a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3.05-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.58,6.58,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.71,8.71,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,249.64,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M256.16,92.31h2.44v2.08a8.23,8.23,0,0,1,1.58-1.57A4.79,4.79,0,0,1,263,92a4.31,4.31,0,0,1,2.81.87,4.5,4.5,0,0,1,1.1,1.44,5.27,5.27,0,0,1,1.92-1.74,5.37,5.37,0,0,1,2.49-.57,4.08,4.08,0,0,1,4,2.14,7,7,0,0,1,.58,3.09V107h-2.56V96.78a2.41,2.41,0,0,0-.73-2,2.93,2.93,0,0,0-1.79-.54,3.53,3.53,0,0,0-2.49,1,4.23,4.23,0,0,0-1.05,3.24V107h-2.5V97.4a5,5,0,0,0-.36-2.18,2.17,2.17,0,0,0-2.09-1,3.59,3.59,0,0,0-2.53,1.08c-.76.72-1.14,2-1.14,3.91V107h-2.47Z" />
-                                  <path class="cls-8 app-tagline" d="M288.53,92.72a5.47,5.47,0,0,1,2.22,1.89,6.67,6.67,0,0,1,1,2.58,17.66,17.66,0,0,1,.21,3.23H281.29a6.42,6.42,0,0,0,1,3.59,3.48,3.48,0,0,0,3,1.35,3.9,3.9,0,0,0,3.06-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5.23,5.23,0,0,1-.64,1.8,6.56,6.56,0,0,1-1.2,1.62,5.7,5.7,0,0,1-2.76,1.48,8.62,8.62,0,0,1-2,.21,6.14,6.14,0,0,1-4.61-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.91-5.72,6.24,6.24,0,0,1,5-2.21A6.58,6.58,0,0,1,288.53,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.53,3.53,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.63,4.63,0,0,0-1.2,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M295.06,92.31h2.34v2.08a6.63,6.63,0,0,1,2.2-1.85,5.91,5.91,0,0,1,2.58-.56c2.08,0,3.49.73,4.21,2.18a7.57,7.57,0,0,1,.61,3.4V107h-2.51V97.73a5,5,0,0,0-.39-2.16,2.41,2.41,0,0,0-2.38-1.37,4.86,4.86,0,0,0-1.44.18,3.7,3.7,0,0,0-1.77,1.2,3.55,3.55,0,0,0-.8,1.5,9.58,9.58,0,0,0-.19,2.21V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M311.13,88.22h2.48v4.09H316v2h-2.34v9.56a1,1,0,0,0,.52,1,2.21,2.21,0,0,0,1,.15h.38l.48,0v2a4.16,4.16,0,0,1-.88.18,7.74,7.74,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88,3.94,3.94,0,0,1-.61-2.29v-9.7h-2v-2h2Z" />
-                                  <path class="cls-8 app-tagline" d="M340.63,86.87v2.39h-6.77V107h-2.75V89.26h-6.76V86.87Z" />
-                                  <path class="cls-8 app-tagline" d="M350.31,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2A8.08,8.08,0,0,1,338.7,100a8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.6,6.6,0,0,1,350.31,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.49,3.49,0,0,0-3.25,1.72,8.07,8.07,0,0,0-1,4.15,7.05,7.05,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.35,3.35,0,0,0,348.78,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M365.88,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2,8.08,8.08,0,0,1-1.77-5.48,8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,365.88,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.46,3.46,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.54,3.54,0,0,0,3.21,1.56A3.35,3.35,0,0,0,364.35,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M370.91,86.87h2.46V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M378.53,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.86,4.86,0,0,0,2.45-.6A2,2,0,0,0,386,103a1.56,1.56,0,0,0-.84-1.43,10.63,10.63,0,0,0-2.14-.7l-2-.49a10,10,0,0,1-2.81-1,3.11,3.11,0,0,1-1.61-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.83,1.94a4.24,4.24,0,0,1,.91,2.65h-2.33A2.72,2.72,0,0,0,385,95a3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.65,1.65,0,0,0-.74,1.4,1.73,1.73,0,0,0,1,1.53,5.69,5.69,0,0,0,1.64.6l1.66.4A12.73,12.73,0,0,1,387,99.75a3.3,3.3,0,0,1,1.44,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43c-2.2,0-3.77-.5-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z" />
-                                  <path class="cls-8 app-tagline" d="M400,87.84c.58-.84,1.68-1.26,3.32-1.26l.48,0,.56,0v2.24l-.56,0h-.32c-.76,0-1.21.19-1.36.58a11.75,11.75,0,0,0-.22,3h2.46v1.94h-2.46V107h-2.43V94.32h-2V92.38h2v-2.3A4.43,4.43,0,0,1,400,87.84Z" />
-                                  <path class="cls-8 app-tagline" d="M417.23,93.77a7.38,7.38,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.18,6.18,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2,8.07,8.07,0,0,1-1.76-5.48,8.83,8.83,0,0,1,1.85-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,417.23,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.47,3.47,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.55,3.55,0,0,0,3.22,1.56A3.35,3.35,0,0,0,415.7,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M422.26,92.31h2.34v2.53A5.61,5.61,0,0,1,426,93,3.68,3.68,0,0,1,428.59,92l.24,0,.56,0v2.6a2.08,2.08,0,0,0-.41-.05l-.4,0a3.52,3.52,0,0,0-2.86,1.2,4.2,4.2,0,0,0-1,2.75V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M439.89,86.87h9a6.09,6.09,0,0,1,4.31,1.51,5.5,5.5,0,0,1,1.64,4.25,6.15,6.15,0,0,1-1.47,4.09,5.5,5.5,0,0,1-4.47,1.74h-6.27V107h-2.72Zm10.55,2.76a5.92,5.92,0,0,0-2.46-.42h-5.37v7H448a5.07,5.07,0,0,0,2.95-.78,3.1,3.1,0,0,0,1.14-2.75A3,3,0,0,0,450.44,89.63Z" />
-                                  <path class="cls-8 app-tagline" d="M468.58,93.77a7.38,7.38,0,0,1,1.95,5.55,9.51,9.51,0,0,1-1.72,5.85,6.17,6.17,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2A8.07,8.07,0,0,1,457,100a8.78,8.78,0,0,1,1.86-5.88,6.23,6.23,0,0,1,5-2.18A6.56,6.56,0,0,1,468.58,93.77Zm-1.52,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.65,3.65,0,0,0-3.55-2,3.48,3.48,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.36,3.36,0,0,0,467.06,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M475,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.93,4.93,0,0,0,2.46-.6,2,2,0,0,0,1.06-1.84,1.55,1.55,0,0,0-.85-1.43,10.4,10.4,0,0,0-2.14-.7l-2-.49a9.78,9.78,0,0,1-2.8-1,3.1,3.1,0,0,1-1.62-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.84,1.94a4.17,4.17,0,0,1,.9,2.65h-2.33a2.72,2.72,0,0,0-.6-1.51,3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.64,1.64,0,0,0-.73,1.4,1.72,1.72,0,0,0,1,1.53,5.66,5.66,0,0,0,1.65.6l1.65.4a12.83,12.83,0,0,1,3.63,1.24,3.31,3.31,0,0,1,1.43,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43q-3.3,0-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z" />
-                                  <path class="cls-8 app-tagline" d="M488,88.22h2.49v4.09h2.34v2h-2.34v9.56a1,1,0,0,0,.52,1,2.19,2.19,0,0,0,.95.15h.39l.48,0v2a4.39,4.39,0,0,1-.89.18,7.52,7.52,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88A3.94,3.94,0,0,1,488,104v-9.7h-2v-2h2Z" />
-                                  <path class="cls-8 app-tagline" d="M503.47,92.9a6.78,6.78,0,0,1,1.41,1.39V92.45h2.27v13.32a10,10,0,0,1-.81,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.1,4.1,0,0,1-1.8-3.32h2.5a2.74,2.74,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.87,0,3.1-.66,3.68-2a11.37,11.37,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,6,6,0,0,1-2.74.54,5.83,5.83,0,0,1-4.15-1.69q-1.77-1.68-1.77-5.58a8.43,8.43,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.38,5.38,0,0,1,503.47,92.9Zm.3,2.64a3.56,3.56,0,0,0-2.85-1.31,3.5,3.5,0,0,0-3.53,2.43,9.48,9.48,0,0,0-.51,3.4,6.12,6.12,0,0,0,1,3.77,3.24,3.24,0,0,0,2.69,1.29,3.75,3.75,0,0,0,3.71-2.39,7.71,7.71,0,0,0,.6-3.16A6.14,6.14,0,0,0,503.77,95.54Z" />
-                                  <path class="cls-8 app-tagline" d="M511,92.31h2.33v2.53a5.91,5.91,0,0,1,1.41-1.8A3.69,3.69,0,0,1,517.3,92l.23,0,.56,0v2.6a2.08,2.08,0,0,0-.4-.05l-.41,0a3.48,3.48,0,0,0-2.85,1.2,4.14,4.14,0,0,0-1,2.75V107H511Z" />
-                                  <path class="cls-8 app-tagline" d="M529.27,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,16.6,16.6,0,0,1,.22,3.23H522a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3-1.28,4.37,4.37,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.34,6.34,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.65,8.65,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,529.27,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M537.9,100.47a5.6,5.6,0,0,0,.78,2.78q1.3,2,4.59,2a7.9,7.9,0,0,0,2.69-.44,3.09,3.09,0,0,0,2.34-3,2.64,2.64,0,0,0-1-2.33,9.55,9.55,0,0,0-3.15-1.19l-2.64-.62a11.41,11.41,0,0,1-3.65-1.33A4.23,4.23,0,0,1,536,92.54a5.86,5.86,0,0,1,1.83-4.44A7.16,7.16,0,0,1,543,86.37a8.75,8.75,0,0,1,5.22,1.52,5.57,5.57,0,0,1,2.15,4.87h-2.56a5.12,5.12,0,0,0-.84-2.47c-.79-1.05-2.14-1.57-4.05-1.57a4.51,4.51,0,0,0-3.31,1,3.2,3.2,0,0,0-1,2.35,2.33,2.33,0,0,0,1.19,2.16,16.76,16.76,0,0,0,3.54,1.09l2.73.65a8.15,8.15,0,0,1,3,1.27,4.81,4.81,0,0,1,1.86,4.09,5.14,5.14,0,0,1-2.37,4.77,10.46,10.46,0,0,1-5.5,1.43,8.07,8.07,0,0,1-5.72-1.91,6.57,6.57,0,0,1-2-5.16Z" />
-                                  <path class="cls-8 app-tagline" d="M573.17,106.9l-1.36,1.65-3.11-2.36a11.33,11.33,0,0,1-2.43,1,10.29,10.29,0,0,1-2.85.37,9.18,9.18,0,0,1-7.32-3.06A11.71,11.71,0,0,1,553.76,97a11.9,11.9,0,0,1,2-7,8.78,8.78,0,0,1,7.69-3.72c3.54,0,6.17,1.14,7.87,3.42a11.08,11.08,0,0,1,2,6.82,14.28,14.28,0,0,1-.48,3.73,9.67,9.67,0,0,1-2.44,4.46ZM565.35,105a3.36,3.36,0,0,0,1.29-.47l-2.22-1.72,1.37-1.68,2.62,2A7.5,7.5,0,0,0,570.1,100a13.76,13.76,0,0,0,.45-3.39,8.48,8.48,0,0,0-1.85-5.7,6.35,6.35,0,0,0-5.07-2.17,6.6,6.6,0,0,0-5.15,2.08q-1.9,2.07-1.9,6.38A8.64,8.64,0,0,0,558.4,103a6.63,6.63,0,0,0,5.36,2.15A11.24,11.24,0,0,0,565.35,105Z" />
-                                  <path class="cls-8 app-tagline" d="M576.58,86.87h2.72v17.69h10.08V107h-12.8Z" />
-                                  <line class="cls-9 app-name-underline" x1="219.17" y1="66.5" x2="384.17" y2="66.5" />
-                               </g>
-                            </svg>
-                        </div>
-                        <h4>{{ _('Feature rich') }} | {{ _('Maximises PostgreSQL') }} | {{ _('Open Source') }} </h4>
-                        <p>
-                            {{ _('pgAdmin is an Open Source administration and management tool for the PostgreSQL database. It includes a graphical administration interface, an SQL query tool, a procedural code debugger and much more. The tool is designed to answer the needs of developers, DBAs and system administrators alike.') }}
-                        </p>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card ">
-                    <div class="card-header">{{ _('Quick Links') }}</div>
-                    <div class="card-body p-2">
-                        <div class="row">
-                            <div class="col-6 dashboard-link">
-                                <a href="#" onclick="pgAdmin.Dashboard.add_new_server()">
-                                    <span class="fa fa-4x dashboard-icon fa-server" aria-hidden="true"></span><br/>
-                                    {{ _('Add New Server') }}
-                                </a>
-                            </div>
-                            <div class="col-6 dashboard-link">
-                                <a href="#" onclick="pgAdmin.Preferences.show()">
-                                    <span id="mnu_preferences" class="fa fa-4x dashboard-icon fa-cogs"
-                                          aria-hidden="true"></span><br/>
-                                    {{ _('Configure pgAdmin') }}
-                                </a>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card ">
-                    <div class="card-header">{{ _('Getting Started') }}</div>
-                    <div class="card-body p-2">
-                        <div class="row">
-                        <div class="col-3 dashboard-link">
-                            <a href="http://www.postgresql.org/docs" target="postgres_help">
-                                <span class="fa fa-4x dashboard-icon dashboard-pg-doc" aria-hidden="true"></span><br/>
-                                {{ _('PostgreSQL Documentation') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="https://www.pgadmin.org" target="pgadmin_website">
-                                <span class="fa fa-4x dashboard-icon fa-globe" aria-hidden="true"></span><br/>
-                                {{ _('pgAdmin Website') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="http://planet.postgresql.org" target="planet_website">
-                                <span class="fa fa-4x dashboard-icon fa-book" aria-hidden="true"></span><br/>
-                                {{ _('Planet PostgreSQL') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="http://www.postgresql.org/community" target="postgres_website">
-                                <span class="fa fa-4x dashboard-icon fa-users" aria-hidden="true"></span><br/>
-                                {{ _('Community Support') }}
-                            </a>
-                        </div>
-                    </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
diff --git a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
new file mode 100644
index 000000000..bbbeba1e9
--- /dev/null
+++ b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
@@ -0,0 +1,277 @@
+import React from 'react';
+import _ from 'lodash';
+import pgAdmin from 'sources/pgadmin';
+import getApiInstance from 'sources/api_instance';
+import { makeStyles } from '@material-ui/core/styles';
+import { Button } from '@mui/material';
+import DeleteIcon from '@mui/icons-material/Delete';
+import DeleteSweepRoundedIcon from '@mui/icons-material/DeleteSweepRounded';
+import { Box } from '@material-ui/core';
+
+import { generateCollectionURL } from '../../browser/static/js/node_ajax';
+import Notify from '../../static/js/helpers/Notifier';
+import gettext from 'sources/gettext';
+import 'wcdocker';
+import PgTable from 'sources/components/PgTable';
+import Theme from 'sources/Theme';
+import PropTypes from 'prop-types';
+
+const useStyles = makeStyles((theme) => ({
+  deleteButton: {
+    padding: '2px',
+    flex: '1',
+    display: 'inheit',
+    overflowY: 'hidden !important',
+    backgroundColour: '#fff !important',
+  },
+  autoResizer: {
+    height: '100% !important',
+    width: '100% !important',
+    background: theme.palette.grey[400],
+    padding: '8px',
+  },
+}));
+
+export function CollectionNodeView({
+  node,
+  treeNodeInfo,
+  itemNodeData,
+  item,
+  pgBrowser
+}) {
+  const classes = useStyles();
+
+  const [data, setData] = React.useState([]);
+  const [selectedObject, setSelectedObject] = React.useState([]);
+  const [reload, setReload] = React.useState();
+
+  const [pgTableColumns, setPgTableColumns] = React.useState([
+    {
+      Header: 'properties',
+      accessor: 'Properties',
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: true,
+    },
+    {
+      Header: 'value',
+      accessor: 'value',
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: true,
+    },
+  ]);
+
+  const getTableSelectedRows = (selRows) => {
+    setSelectedObject(selRows);
+  };
+
+  const onDrop = (type) => {
+    let selRowModels = selectedObject,
+      selRows = [],
+      selItem = pgBrowser.tree.selected(),
+      selectedItemData = selItem ? pgBrowser.tree.itemData(selItem) : null,
+      selNode = selectedItemData && pgBrowser.Nodes[selectedItemData._type],
+      url = undefined,
+      msg = undefined,
+      title = undefined;
+
+    if (selNode && selNode.type && selNode.type == 'coll-constraints') {
+      // In order to identify the constraint type, the type should be passed to the server
+      selRows = selRowModels.map((row) => ({
+        id: row.get('oid'),
+        _type: row.get('_type'),
+      }));
+    } else {
+      selRows = selRowModels.map((row) => row.original.oid);
+    }
+
+    if (selRows.length === 0) {
+      Notify.alert(
+        gettext('Drop Multiple'),
+        gettext('Please select at least one object to delete.')
+      );
+      return;
+    }
+
+    if (!selNode) return;
+
+    if (type === 'dropCascade') {
+      url = selNode.generate_url(selItem, 'delete');
+      msg = gettext(
+        'Are you sure you want to drop all the selected objects and all the objects that depend on them?'
+      );
+      title = gettext('DROP CASCADE multiple objects?');
+    } else {
+      url = selNode.generate_url(selItem, 'drop');
+      msg = gettext('Are you sure you want to drop all the selected objects?');
+      title = gettext('DROP multiple objects?');
+    }
+
+    const api = getApiInstance();
+    let dropNodeProperties = function () {
+      api
+        .delete(url, {
+          data: JSON.stringify({ ids: selRows }),
+          contentType: 'application/json; charset=utf-8',
+        })
+        .then(function (res) {
+          if (res.success == 0) {
+            pgBrowser.report_error(res.errormsg, res.info);
+          } else {
+            pgBrowser.Events.trigger(
+              'pgadmin:browser:tree:refresh',
+              selItem || pgBrowser.tree.selected(),
+              {
+                success: function () {
+                  pgBrowser.tree.select(selItem);
+                  selNode.callbacks.selected.apply(selNode, [selItem]);
+                //   setTimeout(function () {
+                //     pgBrowser.tree.select(selItem);
+                //     selNode.callbacks.selected.apply(selNode, [selItem]);
+                //   }, 100);
+                },
+              }
+            );
+          }
+          setReload(true);
+        })
+        .catch(function (error) {
+          Notify.error(
+            gettext('Error dropping %s', selectedItemData._label.toLowerCase()),
+            error.message
+          );
+        //   Notify.pgNotifier(
+        //     error,
+        //     xhr,
+        //     gettext('Error dropping %s', selectedItemData._label.toLowerCase()),
+        //     function (alertMsg) {
+        //       if (alertMsg == 'CRYPTKEY_SET') {
+        //         onDrop(type);
+        //       } else {
+        //         // $(pgBrowser.panels['properties'].panel).removeData('node-prop');
+        //         pgBrowser.Events.trigger(
+        //           'pgadmin:browser:tree:refresh',
+        //           selItem || pgBrowser.tree.selected(),
+        //           {
+        //             success: function () {
+        //               selNode.callbacks.selected.apply(selNode, [selItem]);
+        //             },
+        //           }
+        //         );
+        //         return true;
+        //       }
+        //     }
+        //   );
+        });
+    };
+
+    if (confirm) {
+      Notify.confirm(title, msg, dropNodeProperties, null);
+    } else {
+      dropNodeProperties();
+    }
+  };
+
+  React.useEffect(() => {
+    let nodeObj =
+      pgAdmin.Browser.Nodes[itemNodeData._type.replace('coll-', '')];
+
+    let schema = nodeObj.getSchema.call(nodeObj, treeNodeInfo, itemNodeData);
+    let url = generateCollectionURL.call(nodeObj, item, 'properties');
+
+    const api = getApiInstance();
+
+    let tableColumns = [];
+
+    if (itemNodeData._type.indexOf('coll-') > -1) {
+      schema.fields.forEach((field) => {
+        if (node.columns.indexOf(field.id) > -1) {
+          var column = {
+            Header: field.label,
+            accessor: field.id,
+            sortble: true,
+            resizable: false,
+            disableGlobalFilter: true,
+          };
+          tableColumns.push(column);
+        }
+      });
+      api({
+        url: url,
+        type: 'GET',
+      })
+        .then((res) => {
+          res.data.forEach((element) => {
+            element['icon'] = '';
+          });
+          setPgTableColumns(tableColumns);
+          setData(res.data);
+        })
+        .catch((err) => {
+          Notify.alert(
+            gettext('Failed to retrieve data from the server.'),
+            gettext(err.message)
+          );
+        });
+    }
+  }, [itemNodeData, node, item, reload]);
+
+  return (
+    <Theme>
+      <Box className={classes.deleteButton}>
+        <Button
+          variant="outlined"
+          startIcon={<DeleteIcon  />}
+          aria-label="Delete/Drop"
+          title={gettext('Delete/Drop')}
+          onClick={() => {
+            // setReload(onDrop('drop'));
+            onDrop('drop');
+          }}
+          disabled={
+            !_.isUndefined(node) && _.isFunction(node.canDrop)
+              ? !node.canDrop.apply(node, [itemNodeData, item])
+              : !node.canDrop
+          }
+        ></Button>
+        <Button
+          variant="outlined"
+          startIcon={<DeleteSweepRoundedIcon />}
+          aria-label="Drop Cascade"
+          title={gettext('Drop Cascade')}
+          onClick={() => {
+            onDrop('dropCascade');
+          }}
+          disabled={
+            !_.isUndefined(node) && _.isFunction(node.canDropCascade)
+              ? !node.canDropCascade.apply(node, [itemNodeData, item])
+              : !node.canDropCascade
+          }
+        ></Button>
+      </Box>
+      <PgTable
+        isSelectRow={true}
+        className={classes.autoResizer}
+        columns={pgTableColumns}
+        data={data}
+        type={'panel'}
+        getSelectedRows={getTableSelectedRows}
+      ></PgTable>
+    </Theme>
+  );
+}
+
+CollectionNodeView.propTypes = {
+  node: PropTypes.func,
+  itemData: PropTypes.object,
+  itemNodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  item: PropTypes.object,
+  pgBrowser: PropTypes.object,
+  preferences: PropTypes.object,
+  sid: PropTypes.number,
+  did: PropTypes.number,
+  row: PropTypes.object,
+  serverConnected: PropTypes.bool,
+};
diff --git a/web/pgadmin/misc/sql/static/js/Sql.jsx b/web/pgadmin/misc/sql/static/js/Sql.jsx
new file mode 100644
index 000000000..5eec57e8d
--- /dev/null
+++ b/web/pgadmin/misc/sql/static/js/Sql.jsx
@@ -0,0 +1,114 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React, { useEffect } from 'react';
+import { generateNodeUrl } from '../../../../browser/static/js/node_ajax';
+import gettext from 'sources/gettext';
+import PropTypes from 'prop-types';
+import Notify from '../../../../static/js/helpers/Notifier';
+import getApiInstance from 'sources/api_instance';
+import { makeStyles } from '@material-ui/core/styles';
+import CodeMirror from '../../../../static/js/components/CodeMirror';
+
+const useStyles = makeStyles((theme) => ({
+  textArea: {
+    height: '100% !important',
+    width: '100% !important',
+    background: theme.palette.grey[400],
+    overflow: 'auto !important',
+    minHeight: '100%',
+    minWidth: '100%',
+  },
+}));
+
+export default function SQL({ nodeData, node, ...props }) {
+  const classes = useStyles();
+  const [nodeSQL, setNodeSQL] = React.useState('');
+
+  const [msg, setMsg] = React.useState('');
+
+  useEffect(() => {
+    var sql = '-- ' + gettext('Please select an object in the tree view.');
+    if (node) {
+      let url = generateNodeUrl.call(
+        node,
+        props.treeNodeInfo,
+        'sql',
+        nodeData,
+        true,
+        node.url_jump_after_node
+      );
+      sql =
+        '-- ' + gettext('No SQL could be generated for the selected object.');
+
+      if (node.hasSQL) {
+        const api = getApiInstance();
+
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            if (res.data.length > 0) {
+              setNodeSQL(res.data);
+            } else {
+              setMsg(sql);
+            }
+          })
+          .catch((e) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(e.message)
+            );
+            // show failed message.
+            setMsg(gettext('Failed to retrieve data from the server.'));
+          });
+      }
+    }
+    if (sql != '') {
+      setMsg(sql);
+    }
+    return () => {
+      setNodeSQL([]);
+    };
+  }, [nodeData]);
+
+  return (
+    <>
+      {nodeSQL.length > 0 ? (
+        <CodeMirror
+          className={classes.textArea}
+          value={nodeSQL}
+          options={{
+            lineNumbers: true,
+            mode: 'text/x-pgsql',
+            readOnly: true,
+          }}
+        />
+      ) : (
+        <CodeMirror
+          className={classes.textArea}
+          value={msg}
+          options={{
+            lineNumbers: true,
+            mode: 'text/x-pgsql',
+            readOnly: true,
+          }}
+        />
+      )}
+    </>
+  );
+}
+
+SQL.propTypes = {
+  res: PropTypes.array,
+  nodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  node: PropTypes.func,
+};
diff --git a/web/pgadmin/misc/sql/static/js/sql.js b/web/pgadmin/misc/sql/static/js/sql.js
deleted file mode 100644
index 57ee3129a..000000000
--- a/web/pgadmin/misc/sql/static/js/sql.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import Notify from '../../../../static/js/helpers/Notifier';
-
-define('misc.sql', [
-  'sources/gettext', 'underscore', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.alertifyjs',
-], function(gettext, _, $, pgAdmin, pgBrowser, Alertify) {
-
-  pgBrowser.ShowNodeSQL = pgBrowser.ShowNodeSQL || {};
-
-  if (pgBrowser.ShowNodeSQL.initialized) {
-    return pgBrowser.ShowNodeSQL;
-  }
-  var wcDocker = window.wcDocker;
-
-  _.extend(pgBrowser.ShowNodeSQL, {
-    init: function() {
-      if (this.initialized) {
-        return;
-      }
-      this.initialized = true;
-      _.bindAll(this, 'showSQL', 'sqlPanelVisibilityChanged');
-
-      var sqlPanels;
-      this.sqlPanels = sqlPanels = pgBrowser.docker.findPanels('sql');
-
-      // We will listend to the visibility change of the SQL panel
-      pgBrowser.Events.on(
-        'pgadmin-browser:panel-sql:' + wcDocker.EVENT.VISIBILITY_CHANGED,
-        this.sqlPanelVisibilityChanged
-      );
-
-      pgBrowser.Events.on(
-        'pgadmin:browser:node:updated',
-        function() {
-          if (this.sqlPanels && this.sqlPanels.length) {
-            $(this.sqlPanels[0]).data('node-prop', '');
-            this.sqlPanelVisibilityChanged(this.sqlPanels[0]);
-          }
-        }, this
-      );
-
-      // Hmm.. Did we find the SQL panel, and is it visible (opened)?
-      // If that is the case - we need to listen the browser tree selection
-      // events.
-      if (sqlPanels.length == 0) {
-        pgBrowser.Events.on(
-          'pgadmin-browser:panel-sql:' + wcDocker.EVENT.INIT,
-          function() {
-            if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) {
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:selected', this.showSQL
-              );
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:reactSelected', this.reactShowSQL
-              );
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:refreshing', this.refreshSQL, this
-              );
-            }
-          }.bind(this)
-        );
-      } else {
-        if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) {
-          pgBrowser.Events.on('pgadmin-browser:tree:selected', this.showSQL);
-          pgBrowser.Events.on('pgadmin-browser:tree:reactSelected', this.reactShowSQL);
-          pgBrowser.Events.on(
-            'pgadmin-browser:tree:refreshing', this.refreshSQL, this
-          );
-        }
-      }
-    },
-    refreshSQL: function(item, data, node) {
-      var that = this,
-        cache_flag = {
-          node_type: data._type,
-          url: node.generate_url(item, 'sql', data, true),
-        };
-
-      if (_.isEqual($(that.sqlPanels[0]).data('node-prop'), cache_flag)) {
-        // Reset the current item selection
-        $(that.sqlPanels[0]).data('node-prop', '');
-        that.showSQL(item, data, node);
-      }
-    },
-    showSQL: function(item, data, node) {
-      /**
-       * We can't start fetching the SQL immediately, it is possible - the user
-       * is just using keyboards to select the node, and just traversing
-       * through. We will wait for some time before fetching the Reversed
-       * Engineering SQL.
-       **/
-
-      this.timeout && clearTimeout(this.timeout);
-
-      var that = this;
-      this.timeout = setTimeout(
-        function() {
-          var sql = '-- ' + gettext('Please select an object in the tree view.');
-          if (node) {
-            sql = '-- ' + gettext('No SQL could be generated for the selected object.');
-            var n_type = data._type,
-              url = node.generate_url(item, 'sql', data, true),
-              treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
-              cache_flag = {
-                node_type: n_type,
-                url: url,
-              };
-
-            // Avoid unnecessary reloads
-            if (_.isEqual($(that.sqlPanels[0]).data('node-prop'), cache_flag)) {
-              return;
-            }
-            // Cache the current IDs for next time
-            $(that.sqlPanels[0]).data('node-prop', cache_flag);
-
-            if (node.hasSQL) {
-
-              sql = '';
-              var timer;
-              var ajaxHook = function() {
-                $.ajax({
-                  url: url,
-                  type: 'GET',
-                  beforeSend: function(xhr) {
-                    xhr.setRequestHeader(
-                      pgAdmin.csrf_token_header, pgAdmin.csrf_token
-                    );
-                    // Generate a timer for the request
-                    timer = setTimeout(function() {
-                      // Notify user if request is taking longer than 1 second
-                      pgAdmin.Browser.editor.setValue(
-                        gettext('Retrieving data from the server...')
-                      );
-                    }, 1000);
-                  },
-                }).done(function(res) {
-                  if (pgAdmin.Browser.editor.getValue() != res) {
-                    pgAdmin.Browser.editor.setValue(res);
-                  }
-                  clearTimeout(timer);
-                }).fail(function(xhr, error, message) {
-                  var _label = treeHierarchy[n_type].label;
-                  pgBrowser.Events.trigger(
-                    'pgadmin:node:retrieval:error', 'sql', xhr, error, message, item
-                  );
-                  if (!Alertify.pgHandleItemError(xhr, error, message, {
-                    item: item,
-                    info: treeHierarchy,
-                  })) {
-                    Notify.pgNotifier(
-                      error, xhr,
-                      gettext('Error retrieving the information - %s', message || _label),
-                      function(msg) {
-                        if(msg === 'CRYPTKEY_SET') {
-                          ajaxHook();
-                        } else {
-                          console.warn(arguments);
-                        }
-                      }
-                    );
-                  }
-                });
-              };
-              ajaxHook();
-            }
-          }
-
-          if (sql != '') {
-            pgAdmin.Browser.editor.setValue(sql);
-          }
-        }, 400);
-    },
-    sqlPanelVisibilityChanged: function(panel) {
-      if (panel.isVisible()) {
-        var t = pgBrowser.tree,
-          i = t.selected(),
-          d = i && t.itemData(i),
-          n = i && d && pgBrowser.Nodes[d._type];
-
-        pgBrowser.ShowNodeSQL.showSQL.apply(pgBrowser.ShowNodeSQL, [i, d, n]);
-
-        // We will start listening the tree selection event.
-        pgBrowser.Events.on('pgadmin-browser:tree:selected', pgBrowser.ShowNodeSQL.showSQL);
-        pgBrowser.Events.on(
-          'pgadmin-browser:tree:refreshing', pgBrowser.ShowNodeSQL.refreshSQL, this
-        );
-      } else {
-        // We don't need to listen the tree item selection event.
-        pgBrowser.Events.off('pgadmin-browser:tree:selected', pgBrowser.ShowNodeSQL.showSQL);
-        pgBrowser.Events.off(
-          'pgadmin-browser:tree:refreshing', pgBrowser.ShowNodeSQL.refreshSQL, this
-        );
-      }
-    },
-  });
-
-  return pgBrowser.ShowNodeSQL;
-});
diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
index 0d259b6d7..eeb190859 100644
--- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx
+++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
@@ -58,7 +58,7 @@ function getColumn(data, singleLineStatistics) {
           accessor: row.name,
           sortble: true,
           resizable: false,
-          disableGlobalFilter: true,
+          disableGlobalFilter: false,
         };
         columns.push(column);
       });
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index f17018a1c..e7015a430 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -8,13 +8,25 @@
 //////////////////////////////////////////////////////////////
 
 import React from 'react';
-import { useTable, useRowSelect, useSortBy, useResizeColumns, useFlexLayout, useGlobalFilter } from 'react-table';
+import {
+  useTable,
+  useRowSelect,
+  useSortBy,
+  useResizeColumns,
+  useFlexLayout,
+  useGlobalFilter,
+  useExpanded,
+} from 'react-table';
 import { FixedSizeList } from 'react-window';
 import { makeStyles } from '@material-ui/core/styles';
 import clsx from 'clsx';
 import PropTypes from 'prop-types';
 import AutoSizer from 'react-virtualized-auto-sizer';
 import { Checkbox } from '@material-ui/core';
+import { InputText } from './FormComponents';
+import FormView from 'sources/SchemaView';
+import { Box } from '@material-ui/core';
+
 /* eslint-disable react/display-name */
 const useStyles = makeStyles((theme) => ({
   root: {
@@ -28,23 +40,56 @@ const useStyles = makeStyles((theme) => ({
     height: '100% !important',
     width: '100% !important',
   },
+  tr:{
+    position: 'unset !important'
+  },
   fixedSizeList: {
     // position: 'relative',
     direction: 'ltr',
     overflowX: 'hidden !important',
-    overflow: 'overlay !important'
+    overflow: 'overlay !important',
+  },
+
+  searchBox: {
+    marginBottom: '1em',
+    display: 'flex',
+    // overflow: 'hidden !important',
+  },
+  tableContentWidth: {
+    width: 'calc(100% - 3px)',
+    position: 'relative'
+
+  },
+  searchPadding: {
+    flex: 2.5
+  },
+  searchInput: {
+    flex: 1,
+    marginTop: 2,
+    borderLeft: 'none',
+    paddingLeft: 5
   },
   table: {
-    flexGrow:1,
-    minHeight:0,
+    flexGrow: 1,
+    minHeight: 0,
     borderSpacing: 0,
     width: '100%',
     overflow: 'hidden',
     borderRadius: theme.shape.borderRadius,
   },
-  extraTable:{
-    backgroundColor: theme.palette.grey[400],
-    flexGrow:1,
+  extraTable: {
+    display: 'flex',
+    flexGrow: 1,
+    overflow: 'hidden !important',
+    // position: 'relative',
+    height: '100% !important',
+    flexDirection: 'column',
+  },
+
+  expandedForm: {
+    borderTopWidth: theme.spacing(0.5),
+    borderStyle: 'solid ',
+    borderColor: theme.palette.grey[400],
   },
 
   tableCell: {
@@ -59,10 +104,9 @@ const useStyles = makeStyles((theme) => ({
     backgroundColor: theme.otherVars.tableBg,
     // ...theme.mixins.panelBorder.top,
     ...theme.mixins.panelBorder.left,
-
   },
   selectCell: {
-    textAlign: 'center'
+    textAlign: 'center',
   },
   tableCellHeader: {
     fontWeight: theme.typography.fontWeightBold,
@@ -93,13 +137,13 @@ const useStyles = makeStyles((theme) => ({
     paddingTop: '0.35em',
     height: 35,
     backgroundPosition: '1%',
-  }
-}),
-);
+  },
+}));
 
 export default function PgTable({ columns, data, isSelectRow, ...props }) {
   // Use the state and functions returned from useTable to build your UI
   const classes = useStyles();
+  const [searchVal, setSearchVal] = React.useState('');
   const defaultColumn = React.useMemo(
     () => ({
       minWidth: 150,
@@ -153,11 +197,12 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     },
     useGlobalFilter,
     useSortBy,
+    useExpanded,
     useRowSelect,
     useResizeColumns,
     useFlexLayout,
-    hooks => {
-      hooks.visibleColumns.push(CLOUMNS => {
+    (hooks) => {
+      hooks.visibleColumns.push((CLOUMNS) => {
         if (isSelectRow) {
           return [
             // Let's make a column for selection
@@ -222,28 +267,47 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
   }, [selectedRowIds]);
 
   React.useEffect(() => {
-    setGlobalFilter(props.searchText || undefined);
-  }, [props.searchText]);
-
+    setGlobalFilter(searchVal || undefined);
+  }, [searchVal]);
 
   const RenderRow = React.useCallback(
     ({ index, style }) => {
       const row = rows[index];
+
+
       prepareRow(row);
       return (
-        <div
-          {...row.getRowProps({
-            style,
-          })}
-          className={classes.tr}
-        >
-          {row.cells.map((cell) => {
-            return (
-              <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classes.tableCell, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={cell.value}>
-                {cell.render('Cell')}
-              </div>
-            );
-          })}
+
+        <div className={classes.tableContentWidth}>
+          <div
+            {...row.getRowProps({
+              style,
+            })}
+            className={classes.tr}
+          >
+            {row.cells.map((cell) => {
+              return (
+                <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classes.tableCell, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={cell.value}>
+                  {cell.render('Cell')}
+                </div>
+              );
+            })}
+          </div>
+
+          {!_.isUndefined(row) && row.isExpanded && (
+            <Box className={classes.expandedForm}>
+              <FormView
+                getInitData={() => {
+                  /*This is intentional (SonarQube)*/
+                }}
+                viewHelperProps={{ mode: 'properties' }}
+                schema={props.schema}
+                showFooter={false}
+                onDataChange={() => { }}
+                className={classes.autoResizer}
+              />
+            </Box>
+          )}
         </div>
       );
     },
@@ -251,62 +315,73 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
   );
   // Render the UI for your table
   return (
-    <AutoSizer className={(props.type ==='panel' ? props.className: classes.autoResizer)}>
-      {({ height}) => (
-        <div {...getTableProps()} className={classes.table}>
-          <div>
-            {headerGroups.map((headerGroup) => (
-              <div key={''} {...headerGroup.getHeaderGroupProps()}>
-                {headerGroup.headers.map((column) => (
-                  <div
-                    key={column.id}
-                    {...column.getHeaderProps()}
-                    className={clsx(
-                      classes.tableCellHeader,
-                      column.className
-                    )}
-                  >
+    <Box className={classes.extraTable}>
+      <Box className={classes.searchBox}>
+        <Box className={classes.searchPadding}></Box>
+        <InputText
+          placeholder={'Search'}
+          className={classes.searchInput}
+          value={searchVal}
+          onChange={(val) => {
+            setSearchVal(val);
+          }}
+        />
+      </Box>
+      <AutoSizer
+        className={props.type === 'panel' ? props.className : classes.autoResizer}
+      >
+        {({ height }) => (
+          <div {...getTableProps()} className={classes.table}>
+            <div>
+              {headerGroups.map((headerGroup) => (
+                <div key={''} {...headerGroup.getHeaderGroupProps()}>
+                  {headerGroup.headers.map((column) => (
                     <div
-                      {...(column.sortble
-                        ? column.getSortByToggleProps()
-                        : {})}
+                      key={column.id}
+                      {...column.getHeaderProps()}
+                      className={clsx(classes.tableCellHeader, column.className)}
                     >
-                      {column.render('Header')}
-                      <span>
-                        {column.isSorted
-                          ? column.isSortedDesc
-                            ? ' 🔽'
-                            : ' 🔼'
-                          : ''}
-                      </span>
-                      {column.resizable && (
-                        <div
-                          {...column.getResizerProps()}
-                          className={classes.resizer}
-                        />
-                      )}
+                      <div
+                        {...(column.sortble ? column.getSortByToggleProps() : {})}
+                      >
+                        {column.render('Header')}
+                        <span>
+                          {column.isSorted
+                            ? column.isSortedDesc
+                              ? ' 🔽'
+                              : ' 🔼'
+                            : ''}
+                        </span>
+                        {column.resizable && (
+                          <div
+                            {...column.getResizerProps()}
+                            className={classes.resizer}
+                          />
+                        )}
+                      </div>
                     </div>
-                  </div>
-                ))}
-                {/* <span className={classes.extraTable}></span> */}
-              </div>
-            ))}
-          </div>
+                  ))}
+                </div>
+              ))}
+            </div>
+
+            <div {...getTableBodyProps()} className={classes}>
+              <FixedSizeList
+                className={classes.fixedSizeList}
+                height={height - 75}
+                itemCount={rows.length}
+                itemSize={35}
+                sorted={props?.sortOptions}
+              >
+                {RenderRow}
+
+              </FixedSizeList>
 
-          <div {...getTableBodyProps()} className={classes}>
-            <FixedSizeList
-              className={classes.fixedSizeList}
-              height={height - 75}
-              itemCount={rows.length}
-              itemSize={35}
-              sorted={props?.sortOptions}
-            >
-              {RenderRow}
-            </FixedSizeList>
+            </div>
           </div>
-        </div>
-      )}
-    </AutoSizer>
+        )}
+      </AutoSizer>
+    </Box>
   );
 }
 
@@ -314,7 +389,10 @@ PgTable.propTypes = {
   stepId: PropTypes.number,
   height: PropTypes.number,
   className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
+  children: PropTypes.oneOfType([
+    PropTypes.arrayOf(PropTypes.node),
+    PropTypes.node,
+  ]),
   getToggleAllRowsSelectedProps: PropTypes.func,
   columns: PropTypes.array,
   data: PropTypes.array,
@@ -324,8 +402,6 @@ PgTable.propTypes = {
   getSelectedRows: PropTypes.func,
   searchText: PropTypes.string,
   type: PropTypes.string,
-  sortOptions:  PropTypes.array,
-
+  sortOptions: PropTypes.array,
+  schema: PropTypes.object
 };
-
-
diff --git a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
index a0f38ea2f..015c3939d 100644
--- a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
+++ b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
@@ -17,7 +17,7 @@ import Wizard from '../../../../static/js/helpers/wizard/Wizard';
 import WizardStep from '../../../../static/js/helpers/wizard/WizardStep';
 import PgTable from 'sources/components/PgTable';
 import { getNodePrivilegeRoleSchema } from '../../../../../pgadmin/browser/server_groups/servers/static/js/privilege.ui.js';
-import { InputSQL, InputText, FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
+import { InputSQL, FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
 import getApiInstance from '../../../../static/js/api_instance';
 import SchemaView from '../../../../static/js/SchemaView';
 import clsx from 'clsx';
@@ -117,7 +117,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
   const [selectedObject, setSelectedObject] = React.useState([]);
   const [selectedAcl, setSelectedAcl] = React.useState({});
   const [msqlData, setSQL] = React.useState('');
-  const [searchVal, setSearchVal] = React.useState('');
   const [loaderText, setLoaderText] = React.useState('');
   const [tablebData, setTableData] = React.useState([]);
   const [privOptions, setPrivOptions] = React.useState({});
@@ -314,17 +313,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
       loaderText={loaderText}
     >
       <WizardStep stepId={0}>
-        <Box className={classes.searchBox}>
-          <Box className={classes.searchPadding}></Box>
-          <InputText
-            placeholder={'Search'}
-            className={classes.searchInput}
-            value={searchVal}
-            onChange={(val) => {
-              setSearchVal(val);}
-            }>
-          </InputText>
-        </Box>
         <Box className={classes.panelContent}>
           <PgTable
             className={classes.table}
@@ -332,7 +320,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
             columns={columns}
             data={tablebData}
             isSelectRow={true}
-            searchText={searchVal}
             getSelectedRows={getTableSelectedRows}>
           </PgTable>
         </Box>
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 3f9c5f8f4..ed9ad4472 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -469,10 +469,8 @@ module.exports = [{
         options: {
           type: 'commonjs',
           imports: [
-            'pure|pgadmin.dashboard',
             'pure|pgadmin.browser.quick_search',
             'pure|pgadmin.tools.user_management',
-            'pure|pgadmin.browser.object_sql',
             'pure|pgadmin.browser.bgprocess',
             'pure|pgadmin.node.server_group',
             'pure|pgadmin.node.server',
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index f45efde88..e5c3e944d 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -208,14 +208,12 @@ var webpackShimConfig = {
     'pgadmin.browser.dialog': path.join(__dirname, './pgadmin/browser/static/js/dialog'),
     'pgadmin.browser.node': path.join(__dirname, './pgadmin/browser/static/js/node'),
     'pgadmin.browser.node.ui': path.join(__dirname, './pgadmin/browser/static/js/node.ui'),
-    'pgadmin.browser.object_sql': path.join(__dirname, './pgadmin/misc/sql/static/js/sql'),
     'pgadmin.browser.panel': path.join(__dirname, './pgadmin/browser/static/js/panel'),
     'pgadmin.browser.toolbar': path.join(__dirname, './pgadmin/browser/static/js/toolbar'),
     'pgadmin.browser.server.privilege': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/privilege'),
     'pgadmin.browser.server.variable': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/variable'),
     'pgadmin.browser.utils': '/browser/js/utils',
     'pgadmin.browser.wizard': path.join(__dirname, './pgadmin/browser/static/js/wizard'),
-    'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/dashboard'),
     'pgadmin.datagrid': path.join(__dirname, './pgadmin/tools/datagrid/static/js/datagrid'),
     'pgadmin.file_manager': path.join(__dirname, './pgadmin/misc/file_manager/static/js/file_manager'),
     'pgadmin.file_utility': path.join(__dirname, './pgadmin/misc/file_manager/static/js/utility'),


^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
@ 2022-03-15 10:31 ` Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Akshay Joshi @ 2022-03-15 10:31 UTC (permalink / raw)
  To: Pradip Parkale <[email protected]>; Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Hi Aditya

Can you please review/test it?

On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
[email protected]> wrote:

> Hi Hackers,
>
> Please find the attached patch for #7132
> <https://redmine.postgresql.org/issues/7132; Port Properties collection,
> Dashboard and SQL panel in React.
>
>
> --
> Thanks & Regards,
> Pradip Parkale
> Software Engineer | EnterpriseDB Corporation
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
@ 2022-03-15 12:09   ` Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Aditya Toshniwal @ 2022-03-15 12:09 UTC (permalink / raw)
  To: Akshay Joshi <[email protected]>; +Cc: Pradip Parkale <[email protected]>; pgadmin-hackers

Hi Pradip,

I did some basic usage and review and found below issues:
1. The code fails if you refresh the page and go to properties, when no
node is selected.
2. I found below UI issues on selecting a database node. Also, checkbox
column is too wide.
[image: image.png]
3. Why is this in the node.js file. It should be in node_view.jsx.

+

+              ReactDOM.render(

+                <Theme>

+                  <CollectionNodeView

+                    node={node}

+                    treeNodeInfo={treeNodeInfo}

+                    item={item}

+                    itemNodeData={d}

+                    pgBrowser={pgBrowser}

+                  ></CollectionNodeView>

+                </Theme>,

+                b.panels['properties'].panel.$container[0]

+              );

4. I have seen a lot of commented codes. Few samples:

+              // if (that.canHide) {


+              // pgBrowser.Events.off('pgadmin-browser:tree:selected', ()
=> {

+

+              //     removePanelView($container[0]);

+              // });

5. In WelcomeDashboard.jsx, the complete SVG code is put. Please move it to
a file and import it.
6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
8. Rename Sql.jsx to SQL.jsx
9. The search is not working. It filters all.
10. If there is huge data then it should show some spinner.
11. Delete buttons should be disabled if no object is selected.
12. Delete buttons and search box should be on the same line.

On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <[email protected]>
wrote:

> Hi Aditya
>
> Can you please review/test it?
>
> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
> [email protected]> wrote:
>
>> Hi Hackers,
>>
>> Please find the attached patch for #7132
>> <https://redmine.postgresql.org/issues/7132; Port Properties collection,
>> Dashboard and SQL panel in React.
>>
>>
>> --
>> Thanks & Regards,
>> Pradip Parkale
>> Software Engineer | EnterpriseDB Corporation
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
> *pgAdmin Hacker | Principal Software Architect*
> *EDB Postgres <http://edbpostgres.com>*
>
> *Mobile: +91 976-788-8246*
>


-- 
Thanks,
Aditya Toshniwal
pgAdmin Hacker | Software Architect | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
@ 2022-03-28 04:37     ` Pradip Parkale <[email protected]>
  2022-03-28 06:28       ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Pradip Parkale @ 2022-03-28 04:37 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: Akshay Joshi <[email protected]>; pgadmin-hackers

Hi,
Here is the updated patch. This patch includes the fix for #7215
<https://redmine.postgresql.org/issues/7215;.

On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
[email protected]> wrote:

> Hi Aditya,
> Please ignore the previous email, find the updated patch attached.
>
> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
> [email protected]> wrote:
>
>> Hi Aditya,
>> Please find the updated patch.
>>
>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>> [email protected]> wrote:
>>
>>> Hi Pradip,
>>>
>>> I did some basic usage and review and found below issues:
>>> 1. The code fails if you refresh the page and go to properties, when no
>>> node is selected.
>>> 2. I found below UI issues on selecting a database node. Also, checkbox
>>> column is too wide.
>>> [image: image.png]
>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>
>>> +
>>>
>>> +              ReactDOM.render(
>>>
>>> +                <Theme>
>>>
>>> +                  <CollectionNodeView
>>>
>>> +                    node={node}
>>>
>>> +                    treeNodeInfo={treeNodeInfo}
>>>
>>> +                    item={item}
>>>
>>> +                    itemNodeData={d}
>>>
>>> +                    pgBrowser={pgBrowser}
>>>
>>> +                  ></CollectionNodeView>
>>>
>>> +                </Theme>,
>>>
>>> +                b.panels['properties'].panel.$container[0]
>>>
>>> +              );
>>>
>>> 4. I have seen a lot of commented codes. Few samples:
>>>
>>> +              // if (that.canHide) {
>>>
>>>
>>> +              // pgBrowser.Events.off('pgadmin-browser:tree:selected',
>>> () => {
>>>
>>> +
>>>
>>> +              //     removePanelView($container[0]);
>>>
>>> +              // });
>>>
>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please move it
>>> to a file and import it.
>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>> 8. Rename Sql.jsx to SQL.jsx
>>> 9. The search is not working. It filters all.
>>> 10. If there is huge data then it should show some spinner.
>>> 11. Delete buttons should be disabled if no object is selected.
>>> 12. Delete buttons and search box should be on the same line.
>>>
>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>> [email protected]> wrote:
>>>
>>>> Hi Aditya
>>>>
>>>> Can you please review/test it?
>>>>
>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Hackers,
>>>>>
>>>>> Please find the attached patch for #7132
>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>> collection, Dashboard and SQL panel in React.
>>>>>
>>>>>
>>>>> --
>>>>> Thanks & Regards,
>>>>> Pradip Parkale
>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>
>>>>
>>>>
>>>> --
>>>> *Thanks & Regards*
>>>> *Akshay Joshi*
>>>> *pgAdmin Hacker | Principal Software Architect*
>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>
>>>> *Mobile: +91 976-788-8246*
>>>>
>>>
>>>
>>> --
>>> Thanks,
>>> Aditya Toshniwal
>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>> <http://edbpostgres.com;
>>> "Don't Complain about Heat, Plant a TREE"
>>>
>>
>>
>> --
>> Thanks & Regards,
>> Pradip Parkale
>> Software Engineer | EnterpriseDB Corporation
>>
>
>
> --
> Thanks & Regards,
> Pradip Parkale
> Software Engineer | EnterpriseDB Corporation
>


-- 
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

  [application/octet-stream] RM7132_v3.patch (877.1K, 4-RM7132_v3.patch)
  download | inline diff:
diff --git a/web/package-lock.json b/web/package-lock.json
new file mode 100755
index 000000000..ccb325595
--- /dev/null
+++ b/web/package-lock.json
@@ -0,0 +1,13194 @@
+{
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "@babel/code-frame": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
+      "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+      "requires": {
+        "@babel/highlight": "^7.12.13"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.13.tgz",
+      "integrity": "sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg==",
+      "dev": true
+    },
+    "@babel/eslint-parser": {
+      "version": "7.12.13",
+      "dev": true,
+      "requires": {
+        "eslint-scope": "5.1.0",
+        "eslint-visitor-keys": "^1.3.0",
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "eslint-scope": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
+          "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.1.0",
+            "estraverse": "^4.1.1"
+          },
+          "dependencies": {
+            "esrecurse": {
+              "version": "4.3.0",
+              "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+              "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+              "dev": true,
+              "requires": {
+                "estraverse": "^5.2.0"
+              },
+              "dependencies": {
+                "estraverse": {
+                  "version": "5.2.0",
+                  "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+                  "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+                  "dev": true
+                }
+              }
+            },
+            "estraverse": {
+              "version": "4.3.0",
+              "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+              "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+              "dev": true
+            }
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/eslint-plugin": {
+      "version": "7.12.13",
+      "dev": true,
+      "requires": {
+        "eslint-rule-composer": "^0.3.0"
+      }
+    },
+    "@babel/generator": {
+      "version": "7.12.15",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
+      "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
+      "requires": {
+        "@babel/types": "^7.12.13",
+        "jsesc": "^2.5.1",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+        }
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz",
+      "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz",
+      "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz",
+      "integrity": "sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.12.13",
+        "@babel/helper-validator-option": "^7.12.11",
+        "browserslist": "^4.14.5",
+        "semver": "^5.5.0"
+      }
+    },
+    "@babel/helper-create-class-features-plugin": {
+      "version": "7.12.16",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz",
+      "integrity": "sha512-KbSEj8l9zYkMVHpQqM3wJNxS1d9h3U9vm/uE5tpjMbaj3lTp+0noe3KPsV5dSD9jxKnf9jO9Ip9FX5PKNZCKow==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/helper-member-expression-to-functions": "^7.12.16",
+        "@babel/helper-optimise-call-expression": "^7.12.13",
+        "@babel/helper-replace-supers": "^7.12.13",
+        "@babel/helper-split-export-declaration": "^7.12.13"
+      },
+      "dependencies": {
+        "@babel/helper-member-expression-to-functions": {
+          "version": "7.12.16",
+          "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz",
+          "integrity": "sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "^7.12.13"
+          }
+        }
+      }
+    },
+    "@babel/helper-create-regexp-features-plugin": {
+      "version": "7.12.16",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.16.tgz",
+      "integrity": "sha512-jAcQ1biDYZBdaAxB4yg46/XirgX7jBDiMHDbwYQOgtViLBXGxJpZQ24jutmBqAIB/q+AwB6j+NbBXjKxEY8vqg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "regexpu-core": "^4.7.1"
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz",
+      "integrity": "sha512-5loeRNvMo9mx1dA/d6yNi+YiKziJZFylZnCo1nmFF4qPU4yJ14abhWESuSMQSlQxWdxdOFzxXjk/PpfudTtYyw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz",
+      "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==",
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.12.13",
+        "@babel/template": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
+      "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.12.13.tgz",
+      "integrity": "sha512-KSC5XSj5HreRhYQtZ3cnSnQwDzgnbdUDEFsxkN0m6Q3WrCRt72xrnZ8+h+pX7YxM7hr87zIO3a/v5p/H3TrnVw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz",
+      "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz",
+      "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz",
+      "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==",
+      "requires": {
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/helper-replace-supers": "^7.12.13",
+        "@babel/helper-simple-access": "^7.12.13",
+        "@babel/helper-split-export-declaration": "^7.12.13",
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.12.13",
+        "@babel/types": "^7.12.13",
+        "lodash": "^4.17.19"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        }
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
+      "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz",
+      "integrity": "sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA=="
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz",
+      "integrity": "sha512-Qa6PU9vNcj1NZacZZI1Mvwt+gXDH6CTfgAkSjeRMLE8HxtDK76+YDId6NQR+z7Rgd5arhD2cIbS74r0SxD6PDA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-wrap-function": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz",
+      "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==",
+      "requires": {
+        "@babel/helper-member-expression-to-functions": "^7.12.13",
+        "@babel/helper-optimise-call-expression": "^7.12.13",
+        "@babel/traverse": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz",
+      "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
+      "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
+      "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.12.11",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+      "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
+    },
+    "@babel/helper-validator-option": {
+      "version": "7.12.16",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz",
+      "integrity": "sha512-uCgsDBPUQDvzr11ePPo4TVEocxj8RXjUVSC/Y8N1YpVAI/XDdUwGJu78xmlGhTxj2ntaWM7n9LQdRtyhOzT2YQ==",
+      "dev": true
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz",
+      "integrity": "sha512-t0aZFEmBJ1LojdtJnhOaQEVejnzYhyjWHSsNSNo8vOYRbAJNh6r6GQF7pd36SqG7OKGbn+AewVQ/0IfYfIuGdw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.13.tgz",
+      "integrity": "sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ==",
+      "requires": {
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz",
+      "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.12.15",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
+      "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA=="
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz",
+      "integrity": "sha512-1KH46Hx4WqP77f978+5Ye/VUbuwQld2hph70yaw2hXS2v7ER2f3nlpNMu909HO2rbvP0NKLlMVDPh9KXklVMhA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-remap-async-to-generator": "^7.12.13",
+        "@babel/plugin-syntax-async-generators": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-dynamic-import": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz",
+      "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-export-namespace-from": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz",
+      "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-json-strings": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz",
+      "integrity": "sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-json-strings": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-logical-assignment-operators": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz",
+      "integrity": "sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-nullish-coalescing-operator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.13.tgz",
+      "integrity": "sha512-Qoxpy+OxhDBI5kRqliJFAl4uWXk3Bn24WeFstPH0iLymFehSAUR8MHpqU7njyXv/qbo7oN6yTy5bfCmXdKpo1Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-numeric-separator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz",
+      "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz",
+      "integrity": "sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-transform-parameters": "^7.12.13"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz",
+      "integrity": "sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-optional-chaining": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.13.tgz",
+      "integrity": "sha512-0ZwjGfTcnZqyV3y9DSD1Yk3ebp+sIUpT2YDqP8hovzaNZnQq2Kd7PEqa6iOIUDBXBt7Jl3P7YAcEIL5Pz8u09Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-private-methods": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.13.tgz",
+      "integrity": "sha512-sV0V57uUwpauixvR7s2o75LmwJI6JECwm5oPUY5beZB1nBl2i37hc7CJGqB5G+58fur5Y6ugvl3LRONk5x34rg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz",
+      "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-async-generators": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-class-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+      "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+      "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-export-namespace-from": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+      "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-jsx": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz",
+      "integrity": "sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==",
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-logical-assignment-operators": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+      "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-numeric-separator": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+      "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-chaining": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+      "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-top-level-await": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz",
+      "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz",
+      "integrity": "sha512-tBtuN6qtCTd+iHzVZVOMNp+L04iIJBpqkdY42tWbmjIT5wvR2kx7gxMBsyhQtFzHwBbyGi9h8J8r9HgnOpQHxg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.13.tgz",
+      "integrity": "sha512-psM9QHcHaDr+HZpRuJcE1PXESuGWSCcbiGFFhhwfzdbTxaGDVzuVtdNYliAwcRo3GFg0Bc8MmI+AvIGYIJG04A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-remap-async-to-generator": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz",
+      "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz",
+      "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz",
+      "integrity": "sha512-cqZlMlhCC1rVnxE5ZGMtIb896ijL90xppMiuWXcwcOAuFczynpd3KYemb91XFFPi3wJSe/OcrX9lXoowatkkxA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/helper-optimise-call-expression": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-replace-supers": "^7.12.13",
+        "@babel/helper-split-export-declaration": "^7.12.13",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz",
+      "integrity": "sha512-dDfuROUPGK1mTtLKyDPUavmj2b6kFu82SmgpztBFEO974KMjJT+Ytj3/oWsTUMBmgPcp9J5Pc1SlcAYRpJ2hRA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz",
+      "integrity": "sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz",
+      "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz",
+      "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz",
+      "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-for-of": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz",
+      "integrity": "sha512-xCbdgSzXYmHGyVX3+BsQjcd4hv4vA/FDy7Kc8eOpzKmBBPEOTurt0w5fCRQaGl+GSBORKgJdstQ1rHl4jbNseQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz",
+      "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz",
+      "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-member-expression-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz",
+      "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz",
+      "integrity": "sha512-JHLOU0o81m5UqG0Ulz/fPC68/v+UTuGTWaZBUwpEk1fYQ1D9LfKV6MPn4ttJKqRo5Lm460fkzjLTL4EHvCprvA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz",
+      "integrity": "sha512-OGQoeVXVi1259HjuoDnsQMlMkT9UkZT9TpXAsqWplS/M0N1g3TJAn/ByOCeQu7mfjc5WpSsRU+jV1Hd89ts0kQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-simple-access": "^7.12.13",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz",
+      "integrity": "sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.12.13",
+        "@babel/helper-module-transforms": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz",
+      "integrity": "sha512-BgZndyABRML4z6ibpi7Z98m4EVLFI9tVsZDADC14AElFaNHHBcJIovflJ6wtCqFxwy2YJ1tJhGRsr0yLPKoN+w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz",
+      "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz",
+      "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz",
+      "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-replace-supers": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz",
+      "integrity": "sha512-e7QqwZalNiBRHCpJg/P8s/VJeSRYgmtWySs1JwvfwPqhBbiWfOcHDKdeAi6oAyIimoKWBlwc8oTgbZHdhCoVZA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-property-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz",
+      "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-react-display-name": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz",
+      "integrity": "sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA==",
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-react-jsx": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.13.tgz",
+      "integrity": "sha512-hhXZMYR8t9RvduN2uW4sjl6MRtUhzNE726JvoJhpjhxKgRUVkZqTsA0xc49ALZxQM7H26pZ/lLvB2Yrea9dllA==",
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-syntax-jsx": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-development": {
+      "version": "7.12.12",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz",
+      "integrity": "sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg==",
+      "requires": {
+        "@babel/plugin-transform-react-jsx": "^7.12.12"
+      }
+    },
+    "@babel/plugin-transform-react-pure-annotations": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz",
+      "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==",
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.10.4",
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz",
+      "integrity": "sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA==",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.14.2"
+      }
+    },
+    "@babel/plugin-transform-reserved-words": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz",
+      "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz",
+      "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz",
+      "integrity": "sha512-dUCrqPIowjqk5pXsx1zPftSq4sT0aCeZVAxhdgs3AMgyaDmoUT0G+5h3Dzja27t76aUEIJWlFgPJqJ/d4dbTtg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz",
+      "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz",
+      "integrity": "sha512-arIKlWYUgmNsF28EyfmiQHJLJFlAJNYkuQO10jL46ggjBpeb2re1P9K9YGxNJB45BqTbaslVysXDYm/g3sN/Qg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz",
+      "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-unicode-escapes": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz",
+      "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz",
+      "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.12.13",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.12.13",
+        "@babel/helper-compilation-targets": "^7.12.13",
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-validator-option": "^7.12.11",
+        "@babel/plugin-proposal-async-generator-functions": "^7.12.13",
+        "@babel/plugin-proposal-class-properties": "^7.12.13",
+        "@babel/plugin-proposal-dynamic-import": "^7.12.1",
+        "@babel/plugin-proposal-export-namespace-from": "^7.12.13",
+        "@babel/plugin-proposal-json-strings": "^7.12.13",
+        "@babel/plugin-proposal-logical-assignment-operators": "^7.12.13",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.13",
+        "@babel/plugin-proposal-numeric-separator": "^7.12.13",
+        "@babel/plugin-proposal-object-rest-spread": "^7.12.13",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.12.13",
+        "@babel/plugin-proposal-optional-chaining": "^7.12.13",
+        "@babel/plugin-proposal-private-methods": "^7.12.13",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.12.13",
+        "@babel/plugin-syntax-async-generators": "^7.8.0",
+        "@babel/plugin-syntax-class-properties": "^7.12.13",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+        "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+        "@babel/plugin-syntax-json-strings": "^7.8.0",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+        "@babel/plugin-syntax-top-level-await": "^7.12.13",
+        "@babel/plugin-transform-arrow-functions": "^7.12.13",
+        "@babel/plugin-transform-async-to-generator": "^7.12.13",
+        "@babel/plugin-transform-block-scoped-functions": "^7.12.13",
+        "@babel/plugin-transform-block-scoping": "^7.12.13",
+        "@babel/plugin-transform-classes": "^7.12.13",
+        "@babel/plugin-transform-computed-properties": "^7.12.13",
+        "@babel/plugin-transform-destructuring": "^7.12.13",
+        "@babel/plugin-transform-dotall-regex": "^7.12.13",
+        "@babel/plugin-transform-duplicate-keys": "^7.12.13",
+        "@babel/plugin-transform-exponentiation-operator": "^7.12.13",
+        "@babel/plugin-transform-for-of": "^7.12.13",
+        "@babel/plugin-transform-function-name": "^7.12.13",
+        "@babel/plugin-transform-literals": "^7.12.13",
+        "@babel/plugin-transform-member-expression-literals": "^7.12.13",
+        "@babel/plugin-transform-modules-amd": "^7.12.13",
+        "@babel/plugin-transform-modules-commonjs": "^7.12.13",
+        "@babel/plugin-transform-modules-systemjs": "^7.12.13",
+        "@babel/plugin-transform-modules-umd": "^7.12.13",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13",
+        "@babel/plugin-transform-new-target": "^7.12.13",
+        "@babel/plugin-transform-object-super": "^7.12.13",
+        "@babel/plugin-transform-parameters": "^7.12.13",
+        "@babel/plugin-transform-property-literals": "^7.12.13",
+        "@babel/plugin-transform-regenerator": "^7.12.13",
+        "@babel/plugin-transform-reserved-words": "^7.12.13",
+        "@babel/plugin-transform-shorthand-properties": "^7.12.13",
+        "@babel/plugin-transform-spread": "^7.12.13",
+        "@babel/plugin-transform-sticky-regex": "^7.12.13",
+        "@babel/plugin-transform-template-literals": "^7.12.13",
+        "@babel/plugin-transform-typeof-symbol": "^7.12.13",
+        "@babel/plugin-transform-unicode-escapes": "^7.12.13",
+        "@babel/plugin-transform-unicode-regex": "^7.12.13",
+        "@babel/preset-modules": "^0.1.3",
+        "@babel/types": "^7.12.13",
+        "core-js-compat": "^3.8.0",
+        "semver": "^5.5.0"
+      },
+      "dependencies": {
+        "@babel/plugin-proposal-class-properties": {
+          "version": "7.12.13",
+          "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz",
+          "integrity": "sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-create-class-features-plugin": "^7.12.13",
+            "@babel/helper-plugin-utils": "^7.12.13"
+          }
+        }
+      }
+    },
+    "@babel/preset-modules": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz",
+      "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+        "@babel/plugin-transform-dotall-regex": "^7.4.4",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      }
+    },
+    "@babel/preset-react": {
+      "version": "7.12.13",
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/plugin-transform-react-display-name": "^7.12.13",
+        "@babel/plugin-transform-react-jsx": "^7.12.13",
+        "@babel/plugin-transform-react-jsx-development": "^7.12.12",
+        "@babel/plugin-transform-react-pure-annotations": "^7.12.1"
+      }
+    },
+    "@babel/runtime": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.13.tgz",
+      "integrity": "sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw==",
+      "dev": true,
+      "requires": {
+        "regenerator-runtime": "^0.13.4"
+      }
+    },
+    "@babel/template": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
+      "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+      "requires": {
+        "@babel/code-frame": "^7.12.13",
+        "@babel/parser": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz",
+      "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==",
+      "requires": {
+        "@babel/code-frame": "^7.12.13",
+        "@babel/generator": "^7.12.13",
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/helper-split-export-declaration": "^7.12.13",
+        "@babel/parser": "^7.12.13",
+        "@babel/types": "^7.12.13",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.19"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        }
+      }
+    },
+    "@babel/types": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz",
+      "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "lodash": "^4.17.19",
+        "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        }
+      }
+    },
+    "@discoveryjs/json-ext": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
+      "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==",
+      "dev": true
+    },
+    "@emotion/cache": {
+      "version": "10.0.29",
+      "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
+      "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==",
+      "dev": true,
+      "requires": {
+        "@emotion/sheet": "0.9.4",
+        "@emotion/stylis": "0.8.5",
+        "@emotion/utils": "0.11.3",
+        "@emotion/weak-memoize": "0.2.5"
+      }
+    },
+    "@emotion/core": {
+      "version": "10.1.1",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.5.5",
+        "@emotion/cache": "^10.0.27",
+        "@emotion/css": "^10.0.27",
+        "@emotion/serialize": "^0.11.15",
+        "@emotion/sheet": "0.9.4",
+        "@emotion/utils": "0.11.3"
+      }
+    },
+    "@emotion/css": {
+      "version": "10.0.27",
+      "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz",
+      "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==",
+      "dev": true,
+      "requires": {
+        "@emotion/serialize": "^0.11.15",
+        "@emotion/utils": "0.11.3",
+        "babel-plugin-emotion": "^10.0.27"
+      }
+    },
+    "@emotion/hash": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
+      "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
+      "dev": true
+    },
+    "@emotion/is-prop-valid": {
+      "version": "0.8.8",
+      "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+      "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+      "dev": true,
+      "requires": {
+        "@emotion/memoize": "0.7.4"
+      }
+    },
+    "@emotion/memoize": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+      "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
+      "dev": true
+    },
+    "@emotion/serialize": {
+      "version": "0.11.16",
+      "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz",
+      "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==",
+      "dev": true,
+      "requires": {
+        "@emotion/hash": "0.8.0",
+        "@emotion/memoize": "0.7.4",
+        "@emotion/unitless": "0.7.5",
+        "@emotion/utils": "0.11.3",
+        "csstype": "^2.5.7"
+      }
+    },
+    "@emotion/sheet": {
+      "version": "0.9.4",
+      "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz",
+      "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==",
+      "dev": true
+    },
+    "@emotion/styled": {
+      "version": "10.0.27",
+      "dev": true,
+      "requires": {
+        "@emotion/styled-base": "^10.0.27",
+        "babel-plugin-emotion": "^10.0.27"
+      }
+    },
+    "@emotion/styled-base": {
+      "version": "10.0.31",
+      "resolved": "https://registry.npmjs.org/@emotion/styled-base/-/styled-base-10.0.31.tgz",
+      "integrity": "sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.5.5",
+        "@emotion/is-prop-valid": "0.8.8",
+        "@emotion/serialize": "^0.11.15",
+        "@emotion/utils": "0.11.3"
+      }
+    },
+    "@emotion/stylis": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+      "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==",
+      "dev": true
+    },
+    "@emotion/unitless": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+      "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
+      "dev": true
+    },
+    "@emotion/utils": {
+      "version": "0.11.3",
+      "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz",
+      "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==",
+      "dev": true
+    },
+    "@emotion/weak-memoize": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
+      "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==",
+      "dev": true
+    },
+    "@eslint/eslintrc": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz",
+      "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.12.4",
+        "debug": "^4.1.1",
+        "espree": "^7.3.0",
+        "globals": "^12.1.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^3.13.1",
+        "lodash": "^4.17.20",
+        "minimatch": "^3.0.4",
+        "strip-json-comments": "^3.1.1"
+      },
+      "dependencies": {
+        "globals": {
+          "version": "12.4.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+          "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true
+        }
+      }
+    },
+    "@nodelib/fs.scandir": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
+      "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "2.0.4",
+        "run-parallel": "^1.1.9"
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
+      "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
+      "dev": true
+    },
+    "@nodelib/fs.walk": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
+      "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.4",
+        "fastq": "^1.6.0"
+      }
+    },
+    "@npmcli/move-file": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+      "dev": true,
+      "requires": {
+        "mkdirp": "^1.0.4",
+        "rimraf": "^3.0.2"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true
+        }
+      }
+    },
+    "@polka/url": {
+      "version": "1.0.0-next.11",
+      "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz",
+      "integrity": "sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA==",
+      "dev": true
+    },
+    "@popperjs/core": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.6.0.tgz",
+      "integrity": "sha512-cPqjjzuFWNK3BSKLm0abspP0sp/IGOli4p5I5fKFAzdS8fvjdOwDCfZqAaIiXd9lPkOWi3SUUfZof3hEb7J/uw=="
+    },
+    "@projectstorm/geometry": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@projectstorm/geometry/-/geometry-6.3.0.tgz",
+      "integrity": "sha512-Fc2JVAkZPnQMAKdn4FtAApvl40S+sUL9E2usRoXcnqRbwmhD3WHBLhmDIvUTArIyKJJOTzyQW4+O7+NcyrK9/Q=="
+    },
+    "@projectstorm/react-canvas-core": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@projectstorm/react-canvas-core/-/react-canvas-core-6.3.0.tgz",
+      "integrity": "sha512-mChKZpdfrTWdGvg1OB0EOaCz5ovC6spY/MJfGtxYek5gU36mjoAXE+L6uLzjELTM3J/TJhDkm3Wd7jW9vCNUyA==",
+      "requires": {
+        "@projectstorm/geometry": "^6.3.0"
+      }
+    },
+    "@projectstorm/react-diagrams": {
+      "version": "6.3.0",
+      "requires": {
+        "@projectstorm/react-diagrams-core": "^6.3.0",
+        "@projectstorm/react-diagrams-defaults": "^6.3.0",
+        "@projectstorm/react-diagrams-routing": "^6.3.0"
+      }
+    },
+    "@projectstorm/react-diagrams-core": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@projectstorm/react-diagrams-core/-/react-diagrams-core-6.3.0.tgz",
+      "integrity": "sha512-xdAA+Rz5vE0adNa/rloXvjDQ2MFlicmdcZHEFTrPH+nV8miAqhHimzbCge8ypAwQyVXS8CLdxUF2RQA/1B8Sng==",
+      "requires": {
+        "@projectstorm/geometry": "^6.3.0",
+        "@projectstorm/react-canvas-core": "^6.3.0"
+      }
+    },
+    "@projectstorm/react-diagrams-defaults": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@projectstorm/react-diagrams-defaults/-/react-diagrams-defaults-6.3.0.tgz",
+      "integrity": "sha512-5qBFg9sSl3OlIt5Edv45uECgkjqjpg+PSRYderOXJjEQi3SYhf9l0YlfMzpTvt5GmVnyX7gQProyt/p/e4e9rQ==",
+      "requires": {
+        "@projectstorm/react-diagrams-core": "^6.3.0"
+      }
+    },
+    "@projectstorm/react-diagrams-routing": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@projectstorm/react-diagrams-routing/-/react-diagrams-routing-6.3.0.tgz",
+      "integrity": "sha512-kgq0MNrjbeEcpQceOORL/5bOQJNF70c/If2x/jqdEKfswzGC9VeUYOKZvzYCRhxsOcpn9hCA6+6Wkd8e4zFzYQ==",
+      "requires": {
+        "@projectstorm/geometry": "^6.3.0",
+        "@projectstorm/react-diagrams-core": "^6.3.0",
+        "@projectstorm/react-diagrams-defaults": "^6.3.0"
+      }
+    },
+    "@simonwep/pickr": {
+      "version": "1.8.0",
+      "requires": {
+        "core-js": "^3.8.0",
+        "nanopop": "^2.1.0"
+      }
+    },
+    "@sindresorhus/is": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
+      "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
+      "dev": true
+    },
+    "@tippyjs/react": {
+      "version": "4.2.0",
+      "requires": {
+        "tippy.js": "^6.2.0"
+      }
+    },
+    "@types/component-emitter": {
+      "version": "1.2.10",
+      "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
+      "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==",
+      "dev": true
+    },
+    "@types/cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==",
+      "dev": true
+    },
+    "@types/cors": {
+      "version": "2.8.10",
+      "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz",
+      "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==",
+      "dev": true
+    },
+    "@types/eslint": {
+      "version": "7.2.6",
+      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
+      "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==",
+      "dev": true,
+      "requires": {
+        "@types/estree": "*",
+        "@types/json-schema": "*"
+      }
+    },
+    "@types/eslint-scope": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz",
+      "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==",
+      "dev": true,
+      "requires": {
+        "@types/eslint": "*",
+        "@types/estree": "*"
+      }
+    },
+    "@types/estree": {
+      "version": "0.0.46",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.46.tgz",
+      "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==",
+      "dev": true
+    },
+    "@types/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+      "dev": true,
+      "requires": {
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/json-schema": {
+      "version": "7.0.7",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
+      "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA=="
+    },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "14.14.25",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz",
+      "integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ=="
+    },
+    "@types/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+      "dev": true
+    },
+    "@types/q": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
+      "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
+      "dev": true
+    },
+    "@vusion/webfonts-generator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/@vusion/webfonts-generator/-/webfonts-generator-0.6.1.tgz",
+      "integrity": "sha512-Y3gxOp/pnL+91xrKahMENSiYKJITkykfuXwCAr4HgQC48KRJhyMgzUgNfpSy7F8V1pxIKaoplgkNueJgWP1z0w==",
+      "dev": true,
+      "requires": {
+        "handlebars": "^4.0.11",
+        "mkdirp": "^0.5.1",
+        "q": "^1.1.2",
+        "svg2ttf": "^5.0.0",
+        "svgicons2svgfont": "^9.0.3",
+        "ttf2eot": "^2.0.0",
+        "ttf2woff": "^2.0.1",
+        "ttf2woff2": "^3.0.0",
+        "underscore": "^1.9.1",
+        "url-join": "^4.0.0"
+      },
+      "dependencies": {
+        "underscore": {
+          "version": "1.12.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
+          "integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ==",
+          "dev": true
+        }
+      }
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz",
+      "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-numbers": "1.11.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.0"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz",
+      "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz",
+      "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz",
+      "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-numbers": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz",
+      "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/floating-point-hex-parser": "1.11.0",
+        "@webassemblyjs/helper-api-error": "1.11.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz",
+      "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz",
+      "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.11.0",
+        "@webassemblyjs/helper-buffer": "1.11.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
+        "@webassemblyjs/wasm-gen": "1.11.0"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz",
+      "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz",
+      "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz",
+      "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz",
+      "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.11.0",
+        "@webassemblyjs/helper-buffer": "1.11.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
+        "@webassemblyjs/helper-wasm-section": "1.11.0",
+        "@webassemblyjs/wasm-gen": "1.11.0",
+        "@webassemblyjs/wasm-opt": "1.11.0",
+        "@webassemblyjs/wasm-parser": "1.11.0",
+        "@webassemblyjs/wast-printer": "1.11.0"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz",
+      "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.11.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
+        "@webassemblyjs/ieee754": "1.11.0",
+        "@webassemblyjs/leb128": "1.11.0",
+        "@webassemblyjs/utf8": "1.11.0"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz",
+      "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.11.0",
+        "@webassemblyjs/helper-buffer": "1.11.0",
+        "@webassemblyjs/wasm-gen": "1.11.0",
+        "@webassemblyjs/wasm-parser": "1.11.0"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz",
+      "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.11.0",
+        "@webassemblyjs/helper-api-error": "1.11.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
+        "@webassemblyjs/ieee754": "1.11.0",
+        "@webassemblyjs/leb128": "1.11.0",
+        "@webassemblyjs/utf8": "1.11.0"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz",
+      "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.11.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webpack-cli/configtest": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.1.tgz",
+      "integrity": "sha512-B+4uBUYhpzDXmwuo3V9yBH6cISwxEI4J+NO5ggDaGEEHb0osY/R7MzeKc0bHURXQuZjMM4qD+bSJCKIuI3eNBQ==",
+      "dev": true
+    },
+    "@webpack-cli/info": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.2.tgz",
+      "integrity": "sha512-5U9kUJHnwU+FhKH4PWGZuBC1hTEPYyxGSL5jjoBI96Gx8qcYJGOikpiIpFoTq8mmgX3im2zAo2wanv/alD74KQ==",
+      "dev": true,
+      "requires": {
+        "envinfo": "^7.7.3"
+      }
+    },
+    "@webpack-cli/serve": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.0.tgz",
+      "integrity": "sha512-k2p2VrONcYVX1wRRrf0f3X2VGltLWcv+JzXRBDmvCxGlCeESx4OXw91TsWeKOkp784uNoVQo313vxJFHXPPwfw==",
+      "dev": true
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
+    },
+    "JSONStream": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+      "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+      "dev": true,
+      "requires": {
+        "jsonparse": "^1.2.0",
+        "through": ">=2.2.7 <3"
+      }
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "dev": true,
+      "requires": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      }
+    },
+    "acorn": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+      "dev": true
+    },
+    "acorn-jsx": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
+      "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+      "dev": true
+    },
+    "acorn-node": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+      "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.0.0",
+        "acorn-walk": "^7.0.0",
+        "xtend": "^4.0.2"
+      },
+      "dependencies": {
+        "acorn-walk": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+          "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+          "dev": true
+        }
+      }
+    },
+    "acorn-walk": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.0.2.tgz",
+      "integrity": "sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A==",
+      "dev": true
+    },
+    "adjust-sourcemap-loader": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz",
+      "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^2.0.0",
+        "regex-parser": "^2.2.11"
+      }
+    },
+    "aggregate-error": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+          "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+          "dev": true
+        }
+      }
+    },
+    "airbnb-prop-types": {
+      "version": "2.16.0",
+      "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz",
+      "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==",
+      "dev": true,
+      "requires": {
+        "array.prototype.find": "^2.1.1",
+        "function.prototype.name": "^1.1.2",
+        "is-regex": "^1.1.0",
+        "object-is": "^1.1.2",
+        "object.assign": "^4.1.0",
+        "object.entries": "^1.1.2",
+        "prop-types": "^15.7.2",
+        "prop-types-exact": "^1.2.0",
+        "react-is": "^16.13.1"
+      }
+    },
+    "ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
+    },
+    "alphanum-sort": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+      "dev": true
+    },
+    "ansi-colors": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+    },
+    "ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^2.0.1"
+      },
+      "dependencies": {
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        }
+      }
+    },
+    "anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "arch": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+      "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+      "dev": true
+    },
+    "archive-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
+      "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
+      "dev": true,
+      "requires": {
+        "file-type": "^4.2.0"
+      },
+      "dependencies": {
+        "file-type": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
+          "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
+          "dev": true
+        }
+      }
+    },
+    "are-we-there-yet": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+      "dev": true,
+      "requires": {
+        "delegates": "^1.0.0",
+        "readable-stream": "^2.0.6"
+      }
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      },
+      "dependencies": {
+        "sprintf-js": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+          "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+          "dev": true
+        }
+      }
+    },
+    "arity-n": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz",
+      "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=",
+      "dev": true
+    },
+    "array-filter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
+      "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-includes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz",
+      "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "get-intrinsic": "^1.0.1",
+        "is-string": "^1.0.5"
+      }
+    },
+    "array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true
+    },
+    "array.prototype.find": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz",
+      "integrity": "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.4"
+      },
+      "dependencies": {
+        "es-abstract": {
+          "version": "1.17.7",
+          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
+          "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
+          "dev": true,
+          "requires": {
+            "es-to-primitive": "^1.2.1",
+            "function-bind": "^1.1.1",
+            "has": "^1.0.3",
+            "has-symbols": "^1.0.1",
+            "is-callable": "^1.2.2",
+            "is-regex": "^1.1.1",
+            "object-inspect": "^1.8.0",
+            "object-keys": "^1.1.1",
+            "object.assign": "^4.1.1",
+            "string.prototype.trimend": "^1.0.1",
+            "string.prototype.trimstart": "^1.0.1"
+          }
+        }
+      }
+    },
+    "array.prototype.flat": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz",
+      "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "array.prototype.flatmap": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz",
+      "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "function-bind": "^1.1.1"
+      }
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+      "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+      "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+      "dev": true
+    },
+    "async": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
+      "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "10.2.4",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.16.1",
+        "caniuse-lite": "^1.0.30001181",
+        "colorette": "^1.2.1",
+        "fraction.js": "^4.0.13",
+        "normalize-range": "^0.1.2",
+        "postcss-value-parser": "^4.1.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+          "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
+          "dev": true
+        }
+      }
+    },
+    "available-typed-arrays": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
+      "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==",
+      "dev": true,
+      "requires": {
+        "array-filter": "^1.0.0"
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.21.1",
+      "requires": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
+    "axios-mock-adapter": {
+      "version": "1.19.0",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^3.1.3",
+        "is-buffer": "^2.0.3"
+      }
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "requires": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "requires": {
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
+          }
+        },
+        "js-tokens": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+        }
+      }
+    },
+    "babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "requires": {
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "detect-indent": "^4.0.0",
+        "jsesc": "^1.3.0",
+        "lodash": "^4.17.4",
+        "source-map": "^0.5.7",
+        "trim-right": "^1.0.1"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+          "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+        }
+      }
+    },
+    "babel-loader": {
+      "version": "8.2.2",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^3.3.1",
+        "loader-utils": "^1.4.0",
+        "make-dir": "^3.1.0",
+        "schema-utils": "^2.6.5"
+      },
+      "dependencies": {
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "1.0.1",
+              "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+              "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+              "dev": true,
+              "requires": {
+                "minimist": "^1.2.0"
+              }
+            }
+          }
+        },
+        "schema-utils": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+          "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+          "dev": true,
+          "requires": {
+            "@types/json-schema": "^7.0.5",
+            "ajv": "^6.12.4",
+            "ajv-keywords": "^3.5.2"
+          },
+          "dependencies": {
+            "ajv-keywords": {
+              "version": "3.5.2",
+              "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+              "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "requires": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "babel-plugin-dynamic-import-node": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+      "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+      "dev": true,
+      "requires": {
+        "object.assign": "^4.1.0"
+      }
+    },
+    "babel-plugin-emotion": {
+      "version": "10.2.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz",
+      "integrity": "sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@emotion/hash": "0.8.0",
+        "@emotion/memoize": "0.7.4",
+        "@emotion/serialize": "^0.11.16",
+        "babel-plugin-macros": "^2.0.0",
+        "babel-plugin-syntax-jsx": "^6.18.0",
+        "convert-source-map": "^1.5.0",
+        "escape-string-regexp": "^1.0.5",
+        "find-root": "^1.1.0",
+        "source-map": "^0.5.7"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "babel-plugin-macros": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
+      "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.7.2",
+        "cosmiconfig": "^6.0.0",
+        "resolve": "^1.12.0"
+      },
+      "dependencies": {
+        "cosmiconfig": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+          "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+          "dev": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.1.0",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.7.2"
+          }
+        }
+      }
+    },
+    "babel-plugin-syntax-jsx": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+      "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
+      "dev": true
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.12",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+          "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
+        },
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+        }
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "lodash": "^4.17.4"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        }
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "requires": {
+        "babel-code-frame": "^6.26.0",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "debug": "^2.6.8",
+        "globals": "^9.18.0",
+        "invariant": "^2.2.2",
+        "lodash": "^4.17.4"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "globals": {
+          "version": "9.18.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+          "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        },
+        "to-fast-properties": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+          "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
+        }
+      }
+    },
+    "babelify": {
+      "version": "10.0.0"
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+    },
+    "backbone": {
+      "version": "1.4.0",
+      "requires": {
+        "underscore": ">=1.8.3"
+      },
+      "dependencies": {
+        "underscore": {
+          "version": "1.12.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
+          "integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ=="
+        }
+      }
+    },
+    "backform": {
+      "version": "0.2.0"
+    },
+    "backgrid": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmjs.org/backgrid/-/backgrid-0.3.8.tgz",
+      "integrity": "sha1-fSaBZ0LXLIWcrTmxPxnJ8nuv/tc=",
+      "requires": {
+        "backbone": "1.1.2 || 1.2.3 || ~1.3.2",
+        "underscore": "^1.8.0"
+      },
+      "dependencies": {
+        "backbone": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.3.3.tgz",
+          "integrity": "sha1-TMgOp8sWMaxHSInOQPL4vGg7KZk=",
+          "requires": {
+            "underscore": ">=1.8.3"
+          }
+        },
+        "underscore": {
+          "version": "1.12.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
+          "integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ=="
+        }
+      }
+    },
+    "backgrid-filter": {
+      "version": "0.3.7",
+      "requires": {
+        "backbone": "~1.2.3",
+        "backgrid": "~0.3.7",
+        "lunr": "^0.7.0",
+        "underscore": "^1.8.3"
+      },
+      "dependencies": {
+        "backbone": {
+          "version": "1.2.3",
+          "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.2.3.tgz",
+          "integrity": "sha1-wiz9B/yG676uYdGJKe0RXpmdZbk=",
+          "requires": {
+            "underscore": ">=1.7.0"
+          }
+        },
+        "underscore": {
+          "version": "1.12.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
+          "integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ=="
+        }
+      }
+    },
+    "backgrid-select-all": {
+      "version": "0.3.5"
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+    },
+    "base64-arraybuffer": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz",
+      "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ=="
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+    },
+    "base64id": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
+    },
+    "bignumber.js": {
+      "version": "9.0.1"
+    },
+    "bin-build": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz",
+      "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==",
+      "dev": true,
+      "requires": {
+        "decompress": "^4.0.0",
+        "download": "^6.2.2",
+        "execa": "^0.7.0",
+        "p-map-series": "^1.0.0",
+        "tempfile": "^2.0.0"
+      }
+    },
+    "bin-check": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz",
+      "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==",
+      "dev": true,
+      "requires": {
+        "execa": "^0.7.0",
+        "executable": "^4.1.0"
+      }
+    },
+    "bin-version": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz",
+      "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==",
+      "dev": true,
+      "requires": {
+        "execa": "^1.0.0",
+        "find-versions": "^3.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "dev": true,
+          "requires": {
+            "nice-try": "^1.0.4",
+            "path-key": "^2.0.1",
+            "semver": "^5.5.0",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "execa": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+          "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^6.0.0",
+            "get-stream": "^4.0.0",
+            "is-stream": "^1.1.0",
+            "npm-run-path": "^2.0.0",
+            "p-finally": "^1.0.0",
+            "signal-exit": "^3.0.0",
+            "strip-eof": "^1.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+          "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        }
+      }
+    },
+    "bin-version-check": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz",
+      "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==",
+      "dev": true,
+      "requires": {
+        "bin-version": "^3.0.0",
+        "semver": "^5.6.0",
+        "semver-truncate": "^1.1.2"
+      }
+    },
+    "bin-wrapper": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz",
+      "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==",
+      "dev": true,
+      "requires": {
+        "bin-check": "^4.1.0",
+        "bin-version-check": "^4.0.0",
+        "download": "^7.1.0",
+        "import-lazy": "^3.1.0",
+        "os-filter-obj": "^2.0.0",
+        "pify": "^4.0.1"
+      },
+      "dependencies": {
+        "download": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz",
+          "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==",
+          "dev": true,
+          "requires": {
+            "archive-type": "^4.0.0",
+            "caw": "^2.0.1",
+            "content-disposition": "^0.5.2",
+            "decompress": "^4.2.0",
+            "ext-name": "^5.0.0",
+            "file-type": "^8.1.0",
+            "filenamify": "^2.0.0",
+            "get-stream": "^3.0.0",
+            "got": "^8.3.1",
+            "make-dir": "^1.2.0",
+            "p-event": "^2.1.0",
+            "pify": "^3.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+              "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+              "dev": true
+            }
+          }
+        },
+        "file-type": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz",
+          "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==",
+          "dev": true
+        },
+        "got": {
+          "version": "8.3.2",
+          "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
+          "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
+          "dev": true,
+          "requires": {
+            "@sindresorhus/is": "^0.7.0",
+            "cacheable-request": "^2.1.1",
+            "decompress-response": "^3.3.0",
+            "duplexer3": "^0.1.4",
+            "get-stream": "^3.0.0",
+            "into-stream": "^3.1.0",
+            "is-retry-allowed": "^1.1.0",
+            "isurl": "^1.0.0-alpha5",
+            "lowercase-keys": "^1.0.0",
+            "mimic-response": "^1.0.0",
+            "p-cancelable": "^0.4.0",
+            "p-timeout": "^2.0.1",
+            "pify": "^3.0.0",
+            "safe-buffer": "^5.1.1",
+            "timed-out": "^4.0.1",
+            "url-parse-lax": "^3.0.0",
+            "url-to-options": "^1.0.1"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+              "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+              "dev": true
+            }
+          }
+        },
+        "make-dir": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+          "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+              "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+              "dev": true
+            }
+          }
+        },
+        "p-cancelable": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+          "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
+          "dev": true
+        },
+        "p-event": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
+          "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
+          "dev": true,
+          "requires": {
+            "p-timeout": "^2.0.1"
+          }
+        },
+        "p-timeout": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+          "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+          "dev": true,
+          "requires": {
+            "p-finally": "^1.0.0"
+          }
+        },
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "dev": true
+        },
+        "url-parse-lax": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+          "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+          "dev": true,
+          "requires": {
+            "prepend-http": "^2.0.0"
+          }
+        }
+      }
+    },
+    "binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "dev": true
+    },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "bl": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+      "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+      "requires": {
+        "readable-stream": "^2.3.5",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "bn.js": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+      "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "bootstrap-datepicker": {
+      "version": "1.9.0",
+      "requires": {
+        "jquery": ">=1.7.1 <4.0.0"
+      },
+      "dependencies": {
+        "jquery": {
+          "version": "3.5.1",
+          "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
+          "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
+        }
+      }
+    },
+    "bootstrap4-toggle": {
+      "version": "3.6.1"
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "requires": {
+        "fill-range": "^7.0.1"
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-pack": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+      "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "combine-source-map": "~0.8.0",
+        "defined": "^1.0.0",
+        "safe-buffer": "^5.1.1",
+        "through2": "^2.0.0",
+        "umd": "^3.0.0"
+      }
+    },
+    "browser-resolve": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
+      "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==",
+      "dev": true,
+      "requires": {
+        "resolve": "^1.17.0"
+      }
+    },
+    "browserify": {
+      "version": "17.0.0",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "assert": "^1.4.0",
+        "browser-pack": "^6.0.1",
+        "browser-resolve": "^2.0.0",
+        "browserify-zlib": "~0.2.0",
+        "buffer": "~5.2.1",
+        "cached-path-relative": "^1.0.0",
+        "concat-stream": "^1.6.0",
+        "console-browserify": "^1.1.0",
+        "constants-browserify": "~1.0.0",
+        "crypto-browserify": "^3.0.0",
+        "defined": "^1.0.0",
+        "deps-sort": "^2.0.1",
+        "domain-browser": "^1.2.0",
+        "duplexer2": "~0.1.2",
+        "events": "^3.0.0",
+        "glob": "^7.1.0",
+        "has": "^1.0.0",
+        "htmlescape": "^1.1.0",
+        "https-browserify": "^1.0.0",
+        "inherits": "~2.0.1",
+        "insert-module-globals": "^7.2.1",
+        "labeled-stream-splicer": "^2.0.0",
+        "mkdirp-classic": "^0.5.2",
+        "module-deps": "^6.2.3",
+        "os-browserify": "~0.3.0",
+        "parents": "^1.0.1",
+        "path-browserify": "^1.0.0",
+        "process": "~0.11.0",
+        "punycode": "^1.3.2",
+        "querystring-es3": "~0.2.0",
+        "read-only-stream": "^2.0.0",
+        "readable-stream": "^2.0.2",
+        "resolve": "^1.1.4",
+        "shasum-object": "^1.0.0",
+        "shell-quote": "^1.6.1",
+        "stream-browserify": "^3.0.0",
+        "stream-http": "^3.0.0",
+        "string_decoder": "^1.1.1",
+        "subarg": "^1.0.0",
+        "syntax-error": "^1.1.1",
+        "through2": "^2.0.0",
+        "timers-browserify": "^1.0.1",
+        "tty-browserify": "0.0.1",
+        "url": "~0.11.0",
+        "util": "~0.12.0",
+        "vm-browserify": "^1.0.0",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+          "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+          "dev": true,
+          "requires": {
+            "base64-js": "^1.0.2",
+            "ieee754": "^1.1.4"
+          }
+        },
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+      "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.0.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+      "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.16.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz",
+      "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30001181",
+        "colorette": "^1.2.1",
+        "electron-to-chromium": "^1.3.649",
+        "escalade": "^3.1.1",
+        "node-releases": "^1.1.70"
+      }
+    },
+    "buffer": {
+      "version": "6.0.3",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.2.1"
+      }
+    },
+    "buffer-alloc": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+      "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+      "requires": {
+        "buffer-alloc-unsafe": "^1.1.0",
+        "buffer-fill": "^1.0.0"
+      }
+    },
+    "buffer-alloc-unsafe": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+      "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg=="
+    },
+    "buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
+    },
+    "buffer-fill": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw="
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "bufferstreams": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-2.0.1.tgz",
+      "integrity": "sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+      "dev": true
+    },
+    "cacache": {
+      "version": "15.0.5",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz",
+      "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==",
+      "dev": true,
+      "requires": {
+        "@npmcli/move-file": "^1.0.1",
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "glob": "^7.1.4",
+        "infer-owner": "^1.0.4",
+        "lru-cache": "^6.0.0",
+        "minipass": "^3.1.1",
+        "minipass-collect": "^1.0.2",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.2",
+        "mkdirp": "^1.0.3",
+        "p-map": "^4.0.0",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^3.0.2",
+        "ssri": "^8.0.0",
+        "tar": "^6.0.2",
+        "unique-filename": "^1.1.1"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true
+        }
+      }
+    },
+    "cacheable-request": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
+      "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
+      "dev": true,
+      "requires": {
+        "clone-response": "1.0.2",
+        "get-stream": "3.0.0",
+        "http-cache-semantics": "3.8.1",
+        "keyv": "3.0.0",
+        "lowercase-keys": "1.0.0",
+        "normalize-url": "2.0.1",
+        "responselike": "1.0.2"
+      },
+      "dependencies": {
+        "lowercase-keys": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+          "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+          "dev": true
+        },
+        "normalize-url": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+          "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+          "dev": true,
+          "requires": {
+            "prepend-http": "^2.0.0",
+            "query-string": "^5.0.1",
+            "sort-keys": "^2.0.0"
+          }
+        },
+        "sort-keys": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+          "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
+          "dev": true,
+          "requires": {
+            "is-plain-obj": "^1.0.0"
+          }
+        }
+      }
+    },
+    "cached-path-relative": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz",
+      "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==",
+      "dev": true
+    },
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "caller-callsite": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+      "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+      "dev": true,
+      "requires": {
+        "callsites": "^2.0.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+          "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+      "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+      "dev": true,
+      "requires": {
+        "caller-callsite": "^2.0.0"
+      }
+    },
+    "callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "^2.0.0",
+        "map-obj": "^1.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+          "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+          "dev": true
+        }
+      }
+    },
+    "caniuse-api": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-lite": "^1.0.0",
+        "lodash.memoize": "^4.1.2",
+        "lodash.uniq": "^4.5.0"
+      },
+      "dependencies": {
+        "lodash.memoize": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+          "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+          "dev": true
+        }
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30001187",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz",
+      "integrity": "sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==",
+      "dev": true
+    },
+    "capture-stack-trace": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
+      "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw=="
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "caw": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz",
+      "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==",
+      "requires": {
+        "get-proxy": "^2.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "tunnel-agent": "^0.6.0",
+        "url-to-options": "^1.0.1"
+      }
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "chart.js": {
+      "version": "2.9.4",
+      "requires": {
+        "chartjs-color": "^2.1.0",
+        "moment": "^2.10.2"
+      },
+      "dependencies": {
+        "moment": {
+          "version": "2.29.1",
+          "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+          "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
+        }
+      }
+    },
+    "chartjs-color": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
+      "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
+      "requires": {
+        "chartjs-color-string": "^0.6.0",
+        "color-convert": "^1.9.3"
+      }
+    },
+    "chartjs-color-string": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
+      "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
+      "requires": {
+        "color-name": "^1.0.0"
+      }
+    },
+    "cheerio": {
+      "version": "1.0.0-rc.5",
+      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.5.tgz",
+      "integrity": "sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==",
+      "dev": true,
+      "requires": {
+        "cheerio-select-tmp": "^0.1.0",
+        "dom-serializer": "~1.2.0",
+        "domhandler": "^4.0.0",
+        "entities": "~2.1.0",
+        "htmlparser2": "^6.0.0",
+        "parse5": "^6.0.0",
+        "parse5-htmlparser2-tree-adapter": "^6.0.0"
+      },
+      "dependencies": {
+        "entities": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+          "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+          "dev": true
+        }
+      }
+    },
+    "cheerio-select-tmp": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz",
+      "integrity": "sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==",
+      "dev": true,
+      "requires": {
+        "css-select": "^3.1.2",
+        "css-what": "^4.0.0",
+        "domelementtype": "^2.1.0",
+        "domhandler": "^4.0.0",
+        "domutils": "^2.4.4"
+      },
+      "dependencies": {
+        "css-select": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz",
+          "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==",
+          "dev": true,
+          "requires": {
+            "boolbase": "^1.0.0",
+            "css-what": "^4.0.0",
+            "domhandler": "^4.0.0",
+            "domutils": "^2.4.3",
+            "nth-check": "^2.0.0"
+          }
+        },
+        "nth-check": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
+          "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
+          "dev": true,
+          "requires": {
+            "boolbase": "^1.0.0"
+          }
+        }
+      }
+    },
+    "chokidar": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
+      "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
+      "dev": true,
+      "requires": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "fsevents": "~2.3.1",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.5.0"
+      }
+    },
+    "chownr": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+      "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "circular-json-es6": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/circular-json-es6/-/circular-json-es6-2.0.2.tgz",
+      "integrity": "sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==",
+      "dev": true
+    },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
+    "cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "requires": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+      "dev": true,
+      "requires": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "closest": {
+      "version": "0.0.1",
+      "requires": {
+        "matches-selector": "0.0.1"
+      }
+    },
+    "coa": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+      "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+      "dev": true,
+      "requires": {
+        "@types/q": "^1.5.1",
+        "chalk": "^2.4.1",
+        "q": "^1.1.2"
+      }
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+    },
+    "codemirror": {
+      "version": "5.59.2"
+    },
+    "color": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
+      "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.1",
+        "color-string": "^1.5.4"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "requires": {
+        "color-name": "1.1.3"
+      },
+      "dependencies": {
+        "color-name": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+        }
+      }
+    },
+    "color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "color-string": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz",
+      "integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==",
+      "dev": true,
+      "requires": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "colorette": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
+      "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw=="
+    },
+    "colors": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+      "dev": true
+    },
+    "combine-source-map": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+      "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "~1.1.0",
+        "inline-source-map": "~0.6.0",
+        "lodash.memoize": "~3.0.3",
+        "source-map": "~0.5.3"
+      },
+      "dependencies": {
+        "convert-source-map": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+          "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+      "dev": true
+    },
+    "compose-function": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz",
+      "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=",
+      "dev": true,
+      "requires": {
+        "arity-n": "^1.0.4"
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "config-chain": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
+      "requires": {
+        "ini": "^1.3.4",
+        "proto-list": "~1.2.1"
+      }
+    },
+    "connect": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+      "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "finalhandler": "1.1.2",
+        "parseurl": "~1.3.3",
+        "utils-merge": "1.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "console-browserify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+      "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+      "dev": true
+    },
+    "console-control-strings": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+      "dev": true
+    },
+    "console-stream": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz",
+      "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=",
+      "dev": true
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.2"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        }
+      }
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        }
+      }
+    },
+    "cookie": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
+      "dev": true
+    },
+    "copy-webpack-plugin": {
+      "version": "7.0.0",
+      "dev": true,
+      "requires": {
+        "fast-glob": "^3.2.4",
+        "glob-parent": "^5.1.1",
+        "globby": "^11.0.1",
+        "loader-utils": "^2.0.0",
+        "normalize-path": "^3.0.0",
+        "p-limit": "^3.0.2",
+        "schema-utils": "^3.0.0",
+        "serialize-javascript": "^5.0.1"
+      }
+    },
+    "core-js": {
+      "version": "3.8.3",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz",
+      "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q=="
+    },
+    "core-js-compat": {
+      "version": "3.8.3",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz",
+      "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.16.1",
+        "semver": "7.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+          "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+          "dev": true
+        }
+      }
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+    },
+    "cors": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4",
+        "vary": "^1"
+      }
+    },
+    "cosmiconfig": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+      "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^2.0.0",
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.13.1",
+        "parse-json": "^4.0.0"
+      },
+      "dependencies": {
+        "import-fresh": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+          "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+          "dev": true,
+          "requires": {
+            "caller-path": "^2.0.0",
+            "resolve-from": "^3.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "resolve-from": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+          "dev": true
+        }
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "create-error-class": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+      "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+      "requires": {
+        "capture-stack-trace": "^1.0.0"
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "cross-env": {
+      "version": "7.0.3",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^7.0.1"
+      }
+    },
+    "cross-spawn": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "dev": true,
+      "requires": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "dependencies": {
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "css": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+      "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "source-map": "^0.6.1",
+        "source-map-resolve": "^0.5.2",
+        "urix": "^0.1.0"
+      }
+    },
+    "css-color-names": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+      "dev": true
+    },
+    "css-declaration-sorter": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
+      "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.1",
+        "timsort": "^0.3.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "css-line-break": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.1.1.tgz",
+      "integrity": "sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==",
+      "requires": {
+        "base64-arraybuffer": "^0.2.0"
+      }
+    },
+    "css-loader": {
+      "version": "5.0.2",
+      "requires": {
+        "camelcase": "^6.2.0",
+        "cssesc": "^3.0.0",
+        "icss-utils": "^5.1.0",
+        "loader-utils": "^2.0.0",
+        "postcss": "^8.2.4",
+        "postcss-modules-extract-imports": "^3.0.0",
+        "postcss-modules-local-by-default": "^4.0.0",
+        "postcss-modules-scope": "^3.0.0",
+        "postcss-modules-values": "^4.0.0",
+        "postcss-value-parser": "^4.1.0",
+        "schema-utils": "^3.0.0",
+        "semver": "^7.3.4"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+          "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg=="
+        },
+        "postcss": {
+          "version": "8.2.5",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.5.tgz",
+          "integrity": "sha512-wMcb7BpDcm3gxQOQx46NDNT36Kk0Ao6PJLLI2ed5vehbbbxCEuslSQzbQ2sfSKy+gkYxhWcGWSeaK+gwm4KIZg==",
+          "requires": {
+            "colorette": "^1.2.1",
+            "nanoid": "^3.1.20",
+            "source-map": "^0.6.1"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+          "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
+        },
+        "semver": {
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        }
+      }
+    },
+    "css-minimizer-webpack-plugin": {
+      "version": "1.2.0",
+      "dev": true,
+      "requires": {
+        "cacache": "^15.0.5",
+        "cssnano": "^4.1.10",
+        "find-cache-dir": "^3.3.1",
+        "jest-worker": "^26.3.0",
+        "p-limit": "^3.0.2",
+        "schema-utils": "^3.0.0",
+        "serialize-javascript": "^5.0.1",
+        "source-map": "^0.6.1",
+        "webpack-sources": "^1.4.3"
+      },
+      "dependencies": {
+        "cssnano": {
+          "version": "4.1.10",
+          "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
+          "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+          "dev": true,
+          "requires": {
+            "cosmiconfig": "^5.0.0",
+            "cssnano-preset-default": "^4.0.7",
+            "is-resolvable": "^1.0.0",
+            "postcss": "^7.0.0"
+          }
+        },
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "css-select": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+      "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
+      "dev": true,
+      "requires": {
+        "boolbase": "^1.0.0",
+        "css-what": "^3.2.1",
+        "domutils": "^1.7.0",
+        "nth-check": "^1.0.2"
+      },
+      "dependencies": {
+        "css-what": {
+          "version": "3.4.2",
+          "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
+          "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
+          "dev": true
+        },
+        "dom-serializer": {
+          "version": "0.2.2",
+          "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+          "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+          "dev": true,
+          "requires": {
+            "domelementtype": "^2.0.1",
+            "entities": "^2.0.0"
+          },
+          "dependencies": {
+            "domelementtype": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
+              "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==",
+              "dev": true
+            }
+          }
+        },
+        "domelementtype": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+          "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+          "dev": true
+        },
+        "domutils": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+          "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+          "dev": true,
+          "requires": {
+            "dom-serializer": "0",
+            "domelementtype": "1"
+          }
+        }
+      }
+    },
+    "css-select-base-adapter": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
+      "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
+      "dev": true
+    },
+    "css-tree": {
+      "version": "1.0.0-alpha.37",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
+      "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
+      "dev": true,
+      "requires": {
+        "mdn-data": "2.0.4",
+        "source-map": "^0.6.1"
+      }
+    },
+    "css-what": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz",
+      "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
+    },
+    "cssnano-preset-default": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
+      "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+      "dev": true,
+      "requires": {
+        "css-declaration-sorter": "^4.0.1",
+        "cssnano-util-raw-cache": "^4.0.1",
+        "postcss": "^7.0.0",
+        "postcss-calc": "^7.0.1",
+        "postcss-colormin": "^4.0.3",
+        "postcss-convert-values": "^4.0.1",
+        "postcss-discard-comments": "^4.0.2",
+        "postcss-discard-duplicates": "^4.0.2",
+        "postcss-discard-empty": "^4.0.1",
+        "postcss-discard-overridden": "^4.0.1",
+        "postcss-merge-longhand": "^4.0.11",
+        "postcss-merge-rules": "^4.0.3",
+        "postcss-minify-font-values": "^4.0.2",
+        "postcss-minify-gradients": "^4.0.2",
+        "postcss-minify-params": "^4.0.2",
+        "postcss-minify-selectors": "^4.0.2",
+        "postcss-normalize-charset": "^4.0.1",
+        "postcss-normalize-display-values": "^4.0.2",
+        "postcss-normalize-positions": "^4.0.2",
+        "postcss-normalize-repeat-style": "^4.0.2",
+        "postcss-normalize-string": "^4.0.2",
+        "postcss-normalize-timing-functions": "^4.0.2",
+        "postcss-normalize-unicode": "^4.0.1",
+        "postcss-normalize-url": "^4.0.1",
+        "postcss-normalize-whitespace": "^4.0.2",
+        "postcss-ordered-values": "^4.1.2",
+        "postcss-reduce-initial": "^4.0.3",
+        "postcss-reduce-transforms": "^4.0.2",
+        "postcss-svgo": "^4.0.2",
+        "postcss-unique-selectors": "^4.0.1"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "cssnano-util-get-arguments": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
+      "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
+      "dev": true
+    },
+    "cssnano-util-get-match": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
+      "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
+      "dev": true
+    },
+    "cssnano-util-raw-cache": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
+      "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "cssnano-util-same-parent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
+      "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
+      "dev": true
+    },
+    "csso": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+      "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+      "dev": true,
+      "requires": {
+        "css-tree": "^1.1.2"
+      },
+      "dependencies": {
+        "css-tree": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz",
+          "integrity": "sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==",
+          "dev": true,
+          "requires": {
+            "mdn-data": "2.0.14",
+            "source-map": "^0.6.1"
+          }
+        },
+        "mdn-data": {
+          "version": "2.0.14",
+          "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+          "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+          "dev": true
+        }
+      }
+    },
+    "csstype": {
+      "version": "2.6.14",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz",
+      "integrity": "sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A==",
+      "dev": true
+    },
+    "cubic2quad": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/cubic2quad/-/cubic2quad-1.1.1.tgz",
+      "integrity": "sha1-abGcYaP1tB7PLx1fro+wNBWqixU=",
+      "dev": true
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "^1.0.1"
+      }
+    },
+    "custom-event": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+      "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+      "dev": true
+    },
+    "d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "requires": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
+    "dagre": {
+      "version": "0.8.5",
+      "requires": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        }
+      }
+    },
+    "dash-ast": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+      "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "date-format": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
+      "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==",
+      "dev": true
+    },
+    "debug": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "decompress": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz",
+      "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==",
+      "requires": {
+        "decompress-tar": "^4.0.0",
+        "decompress-tarbz2": "^4.0.0",
+        "decompress-targz": "^4.0.0",
+        "decompress-unzip": "^4.0.1",
+        "graceful-fs": "^4.1.10",
+        "make-dir": "^1.0.0",
+        "pify": "^2.3.0",
+        "strip-dirs": "^2.0.0"
+      },
+      "dependencies": {
+        "make-dir": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+          "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+          "requires": {
+            "pify": "^3.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+              "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+            }
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+        }
+      }
+    },
+    "decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "requires": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "decompress-tar": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+      "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+      "requires": {
+        "file-type": "^5.2.0",
+        "is-stream": "^1.1.0",
+        "tar-stream": "^1.5.2"
+      }
+    },
+    "decompress-tarbz2": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+      "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+      "requires": {
+        "decompress-tar": "^4.1.0",
+        "file-type": "^6.1.0",
+        "is-stream": "^1.1.0",
+        "seek-bzip": "^1.0.5",
+        "unbzip2-stream": "^1.0.9"
+      },
+      "dependencies": {
+        "file-type": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+          "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg=="
+        }
+      }
+    },
+    "decompress-targz": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+      "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+      "requires": {
+        "decompress-tar": "^4.1.1",
+        "file-type": "^5.2.0",
+        "is-stream": "^1.1.0"
+      }
+    },
+    "decompress-unzip": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+      "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+      "requires": {
+        "file-type": "^3.8.0",
+        "get-stream": "^2.2.0",
+        "pify": "^2.3.0",
+        "yauzl": "^2.4.2"
+      },
+      "dependencies": {
+        "file-type": {
+          "version": "3.9.0",
+          "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+          "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
+        },
+        "get-stream": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+          "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+          "requires": {
+            "object-assign": "^4.0.1",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+        }
+      }
+    },
+    "deep-equal-ident": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz",
+      "integrity": "sha1-BvS4nlNxDNbOpKd4HHqVZkLejck=",
+      "dev": true,
+      "requires": {
+        "lodash.isequal": "^3.0"
+      },
+      "dependencies": {
+        "lodash.isequal": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz",
+          "integrity": "sha1-HDXrO27wzR/1F0Pj6jz3/f/ay2Q=",
+          "dev": true,
+          "requires": {
+            "lodash._baseisequal": "^3.0.0",
+            "lodash._bindcallback": "^3.0.0"
+          }
+        }
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "defined": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+      "dev": true
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "delegates": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "deps-sort": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz",
+      "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "shasum-object": "^1.0.0",
+        "subarg": "^1.0.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "requires": {
+        "repeating": "^2.0.0"
+      }
+    },
+    "detective": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
+      "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==",
+      "dev": true,
+      "requires": {
+        "acorn-node": "^1.6.1",
+        "defined": "^1.0.0",
+        "minimist": "^1.1.1"
+      }
+    },
+    "di": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+      "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "requires": {
+        "path-type": "^4.0.0"
+      }
+    },
+    "discontinuous-range": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+      "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=",
+      "dev": true
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "dom-serialize": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+      "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+      "dev": true,
+      "requires": {
+        "custom-event": "~1.0.0",
+        "ent": "~2.2.0",
+        "extend": "^3.0.0",
+        "void-elements": "^2.0.0"
+      }
+    },
+    "dom-serializer": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz",
+      "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.0.0",
+        "entities": "^2.0.0"
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
+      "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==",
+      "dev": true
+    },
+    "domhandler": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
+      "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.1.0"
+      }
+    },
+    "domutils": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz",
+      "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "^1.0.1",
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.0.0"
+      }
+    },
+    "dot-prop": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+      "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+      "dev": true,
+      "requires": {
+        "is-obj": "^2.0.0"
+      }
+    },
+    "download": {
+      "version": "6.2.5",
+      "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz",
+      "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==",
+      "dev": true,
+      "requires": {
+        "caw": "^2.0.0",
+        "content-disposition": "^0.5.2",
+        "decompress": "^4.0.0",
+        "ext-name": "^5.0.0",
+        "file-type": "5.2.0",
+        "filenamify": "^2.0.0",
+        "get-stream": "^3.0.0",
+        "got": "^7.0.0",
+        "make-dir": "^1.0.0",
+        "p-event": "^1.0.0",
+        "pify": "^3.0.0"
+      },
+      "dependencies": {
+        "make-dir": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+          "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          }
+        }
+      }
+    },
+    "dropzone": {
+      "version": "5.7.6"
+    },
+    "duplexer": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+      "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+      "dev": true
+    },
+    "duplexer2": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "ejs": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.0.2.tgz",
+      "integrity": "sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA==",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.665",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.665.tgz",
+      "integrity": "sha512-LIjx1JheOz7LM8DMEQ2tPnbBzJ4nVG1MKutsbEMLnJfwfVdPIsyagqfLp56bOWhdBrYGXWHaTayYkllIU2TauA==",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.5.4",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+      "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.11.9",
+        "brorand": "^1.1.0",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.1",
+        "inherits": "^2.0.4",
+        "minimalistic-assert": "^1.0.1",
+        "minimalistic-crypto-utils": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "engine.io": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz",
+      "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.4",
+        "base64id": "2.0.0",
+        "cookie": "~0.4.1",
+        "cors": "~2.8.5",
+        "debug": "~4.3.1",
+        "engine.io-parser": "~4.0.0",
+        "ws": "~7.4.2"
+      }
+    },
+    "engine.io-parser": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
+      "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
+      "dev": true,
+      "requires": {
+        "base64-arraybuffer": "0.1.4"
+      },
+      "dependencies": {
+        "base64-arraybuffer": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+          "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=",
+          "dev": true
+        }
+      }
+    },
+    "enhanced-resolve": {
+      "version": "5.7.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz",
+      "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      }
+    },
+    "enquirer": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^4.1.1"
+      }
+    },
+    "ent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+      "dev": true
+    },
+    "entities": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+      "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+      "dev": true
+    },
+    "envinfo": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.4.tgz",
+      "integrity": "sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==",
+      "dev": true
+    },
+    "enzyme": {
+      "version": "3.11.0",
+      "dev": true,
+      "requires": {
+        "array.prototype.flat": "^1.2.3",
+        "cheerio": "^1.0.0-rc.3",
+        "enzyme-shallow-equal": "^1.0.1",
+        "function.prototype.name": "^1.1.2",
+        "has": "^1.0.3",
+        "html-element-map": "^1.2.0",
+        "is-boolean-object": "^1.0.1",
+        "is-callable": "^1.1.5",
+        "is-number-object": "^1.0.4",
+        "is-regex": "^1.0.5",
+        "is-string": "^1.0.5",
+        "is-subset": "^0.1.1",
+        "lodash.escape": "^4.0.1",
+        "lodash.isequal": "^4.5.0",
+        "object-inspect": "^1.7.0",
+        "object-is": "^1.0.2",
+        "object.assign": "^4.1.0",
+        "object.entries": "^1.1.1",
+        "object.values": "^1.1.1",
+        "raf": "^3.4.1",
+        "rst-selector-parser": "^2.2.3",
+        "string.prototype.trim": "^1.2.1"
+      },
+      "dependencies": {
+        "raf": {
+          "version": "3.4.1",
+          "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+          "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+          "dev": true,
+          "requires": {
+            "performance-now": "^2.1.0"
+          }
+        }
+      }
+    },
+    "enzyme-adapter-react-16": {
+      "version": "1.15.6",
+      "dev": true,
+      "requires": {
+        "enzyme-adapter-utils": "^1.14.0",
+        "enzyme-shallow-equal": "^1.0.4",
+        "has": "^1.0.3",
+        "object.assign": "^4.1.2",
+        "object.values": "^1.1.2",
+        "prop-types": "^15.7.2",
+        "react-is": "^16.13.1",
+        "react-test-renderer": "^16.0.0-0",
+        "semver": "^5.7.0"
+      }
+    },
+    "enzyme-adapter-utils": {
+      "version": "1.14.0",
+      "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz",
+      "integrity": "sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==",
+      "dev": true,
+      "requires": {
+        "airbnb-prop-types": "^2.16.0",
+        "function.prototype.name": "^1.1.3",
+        "has": "^1.0.3",
+        "object.assign": "^4.1.2",
+        "object.fromentries": "^2.0.3",
+        "prop-types": "^15.7.2",
+        "semver": "^5.7.1"
+      }
+    },
+    "enzyme-matchers": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz",
+      "integrity": "sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==",
+      "dev": true,
+      "requires": {
+        "circular-json-es6": "^2.0.1",
+        "deep-equal-ident": "^1.1.1"
+      }
+    },
+    "enzyme-shallow-equal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz",
+      "integrity": "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3",
+        "object-is": "^1.1.2"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.18.0-next.2",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz",
+      "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.1",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.9.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.2",
+        "string.prototype.trimend": "^1.0.3",
+        "string.prototype.trimstart": "^1.0.3"
+      }
+    },
+    "es-module-lexer": {
+      "version": "0.3.26",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz",
+      "integrity": "sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==",
+      "dev": true
+    },
+    "es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+      "dev": true,
+      "requires": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+      "dev": true,
+      "requires": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+    },
+    "eslint": {
+      "version": "7.19.0",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@eslint/eslintrc": "^0.3.0",
+        "ajv": "^6.10.0",
+        "chalk": "^4.0.0",
+        "cross-spawn": "^7.0.2",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "enquirer": "^2.3.5",
+        "eslint-scope": "^5.1.1",
+        "eslint-utils": "^2.1.0",
+        "eslint-visitor-keys": "^2.0.0",
+        "espree": "^7.3.1",
+        "esquery": "^1.2.0",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^6.0.0",
+        "functional-red-black-tree": "^1.0.1",
+        "glob-parent": "^5.0.0",
+        "globals": "^12.1.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.4.1",
+        "lodash": "^4.17.20",
+        "minimatch": "^3.0.4",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.9.1",
+        "progress": "^2.0.0",
+        "regexpp": "^3.1.0",
+        "semver": "^7.2.1",
+        "strip-ansi": "^6.0.0",
+        "strip-json-comments": "^3.1.0",
+        "table": "^6.0.4",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+          "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "doctrine": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+          "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2"
+          }
+        },
+        "eslint-visitor-keys": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
+          "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
+          "dev": true
+        },
+        "globals": {
+          "version": "12.4.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+          "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        },
+        "semver": {
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-plugin-react": {
+      "version": "7.22.0",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.1.1",
+        "array.prototype.flatmap": "^1.2.3",
+        "doctrine": "^2.1.0",
+        "has": "^1.0.3",
+        "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+        "object.entries": "^1.1.2",
+        "object.fromentries": "^2.0.2",
+        "object.values": "^1.1.1",
+        "prop-types": "^15.7.2",
+        "resolve": "^1.18.1",
+        "string.prototype.matchall": "^4.0.2"
+      }
+    },
+    "eslint-rule-composer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz",
+      "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+      "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+      "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+      "dev": true
+    },
+    "espree": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.4.0",
+        "acorn-jsx": "^5.3.1",
+        "eslint-visitor-keys": "^1.3.0"
+      }
+    },
+    "esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^5.1.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+          "dev": true
+        }
+      }
+    },
+    "esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^5.2.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+          "dev": true
+        }
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+    },
+    "eve": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/eve/-/eve-0.5.4.tgz",
+      "integrity": "sha1-Z9CAuXJSkdfjieNMJoYN2X8d66o="
+    },
+    "eventemitter3": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+      "dev": true
+    },
+    "events": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
+      "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
+      "dev": true
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "exec-buffer": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz",
+      "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==",
+      "dev": true,
+      "requires": {
+        "execa": "^0.7.0",
+        "p-finally": "^1.0.0",
+        "pify": "^3.0.0",
+        "rimraf": "^2.5.4",
+        "tempfile": "^2.0.0"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+          "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
+      }
+    },
+    "execa": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^5.0.1",
+        "get-stream": "^3.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "executable": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
+      "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
+      "dev": true,
+      "requires": {
+        "pify": "^2.2.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "exports-loader": {
+      "version": "2.0.0",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      }
+    },
+    "ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "requires": {
+        "type": "^2.0.0"
+      },
+      "dependencies": {
+        "type": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/type/-/type-2.2.0.tgz",
+          "integrity": "sha512-M/u37b4oSGlusaU8ZB96BfFPWQ8MbsZYXB+kXGMiDj6IKinkcNaQvmirBuWj8mAXqP6LYn1rQvbTYum3yPhaOA==",
+          "dev": true
+        }
+      }
+    },
+    "ext-list": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
+      "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
+      "dev": true,
+      "requires": {
+        "mime-db": "^1.28.0"
+      }
+    },
+    "ext-name": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
+      "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
+      "dev": true,
+      "requires": {
+        "ext-list": "^2.0.0",
+        "sort-keys-length": "^1.0.0"
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+    },
+    "fast-glob": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
+      "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.0",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.2",
+        "picomatch": "^2.2.1"
+      }
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fast-safe-stringify": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
+      "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==",
+      "dev": true
+    },
+    "fastest-levenshtein": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
+      "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
+      "dev": true
+    },
+    "fastq": {
+      "version": "1.10.1",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.1.tgz",
+      "integrity": "sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA==",
+      "dev": true,
+      "requires": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "fd-slicer": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+      "requires": {
+        "pend": "~1.2.0"
+      }
+    },
+    "figures": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+      "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5",
+        "object-assign": "^4.1.0"
+      }
+    },
+    "file-entry-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
+      "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^3.0.4"
+      }
+    },
+    "file-exists": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-exists/-/file-exists-2.0.0.tgz",
+      "integrity": "sha1-okFQZlFQ5i1VvFRJKB2I0rCBDco="
+    },
+    "file-type": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY="
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true
+    },
+    "filename-reserved-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+      "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik="
+    },
+    "filenamify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz",
+      "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==",
+      "requires": {
+        "filename-reserved-regex": "^2.0.0",
+        "strip-outer": "^1.0.0",
+        "trim-repeated": "^1.0.0"
+      }
+    },
+    "fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "requires": {
+        "to-regex-range": "^5.0.1"
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+      "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^3.0.2",
+        "pkg-dir": "^4.1.0"
+      }
+    },
+    "find-root": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+      "dev": true
+    },
+    "find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "requires": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      }
+    },
+    "find-versions": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
+      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
+      "dev": true,
+      "requires": {
+        "semver-regex": "^2.0.0"
+      }
+    },
+    "flat-cache": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+      "dev": true,
+      "requires": {
+        "flatted": "^3.1.0",
+        "rimraf": "^3.0.2"
+      },
+      "dependencies": {
+        "flatted": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
+          "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
+          "dev": true
+        }
+      }
+    },
+    "flatted": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+      "dev": true
+    },
+    "follow-redirects": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
+      "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA=="
+    },
+    "foreach": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+      "dev": true
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "fraction.js": {
+      "version": "4.0.13",
+      "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz",
+      "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "fs-constants": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+    },
+    "fs-extra": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "function.prototype.name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.3.tgz",
+      "integrity": "sha512-H51qkbNSp8mtkJt+nyW1gyStBiKZxfRqySNUR99ylq6BPXHKI4SEvIlTKp4odLfjRKJV04DFWMU3G/YRlQOsag==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "functions-have-names": "^1.2.1"
+      }
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "functions-have-names": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz",
+      "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==",
+      "dev": true
+    },
+    "gauge": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.0.3",
+        "console-control-strings": "^1.0.0",
+        "has-unicode": "^2.0.0",
+        "object-assign": "^4.1.0",
+        "signal-exit": "^3.0.0",
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wide-align": "^1.1.0"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        }
+      }
+    },
+    "gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
+    },
+    "geometry-interfaces": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/geometry-interfaces/-/geometry-interfaces-1.1.4.tgz",
+      "integrity": "sha512-qD6OdkT6NcES9l4Xx3auTpwraQruU7dARbQPVO71MKvkGYw5/z/oIiGymuFXrRaEQa5Y67EIojUpaLeGEa5hGA==",
+      "dev": true
+    },
+    "get-assigned-identifiers": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+      "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true
+    },
+    "get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "get-proxy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz",
+      "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==",
+      "requires": {
+        "npm-conf": "^1.1.0"
+      }
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "glob-to-regexp": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+      "dev": true
+    },
+    "globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+    },
+    "globby": {
+      "version": "11.0.2",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz",
+      "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==",
+      "dev": true,
+      "requires": {
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.1.1",
+        "ignore": "^5.1.4",
+        "merge2": "^1.3.0",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "ignore": {
+          "version": "5.1.8",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+          "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+          "dev": true
+        }
+      }
+    },
+    "got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "dev": true,
+      "requires": {
+        "decompress-response": "^3.2.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "is-plain-obj": "^1.1.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "isurl": "^1.0.0-alpha5",
+        "lowercase-keys": "^1.0.0",
+        "p-cancelable": "^0.3.0",
+        "p-timeout": "^1.1.1",
+        "safe-buffer": "^5.0.1",
+        "timed-out": "^4.0.0",
+        "url-parse-lax": "^1.0.0",
+        "url-to-options": "^1.0.1"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
+    },
+    "graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "requires": {
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        }
+      }
+    },
+    "gzip-size": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz",
+      "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.2"
+      }
+    },
+    "handlebars": {
+      "version": "4.7.7",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+      "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5",
+        "neo-async": "^2.6.0",
+        "source-map": "^0.6.1",
+        "uglify-js": "^3.1.4",
+        "wordwrap": "^1.0.0"
+      }
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+    },
+    "has-symbol-support-x": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw=="
+    },
+    "has-symbols": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+      "dev": true
+    },
+    "has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "requires": {
+        "has-symbol-support-x": "^1.4.1"
+      }
+    },
+    "has-unicode": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+      "dev": true
+    },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "hat": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz",
+      "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=",
+      "dev": true
+    },
+    "heap": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.5.tgz",
+      "integrity": "sha1-cTtlWQ68xA/L7q9V6FFpQJKzmvE="
+    },
+    "hex-color-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
+      "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
+      "dev": true
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+      "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+      "dev": true
+    },
+    "hsl-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
+      "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
+      "dev": true
+    },
+    "hsla-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
+      "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
+      "dev": true
+    },
+    "html-comment-regex": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
+      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
+      "dev": true
+    },
+    "html-element-map": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.0.tgz",
+      "integrity": "sha512-AqCt/m9YaiMwaaAyOPdq4Ga0cM+jdDWWGueUMkdROZcTeClaGpN0AQeyGchZhTegQoABmc6+IqH7oCR/8vhQYg==",
+      "dev": true,
+      "requires": {
+        "array-filter": "^1.0.0",
+        "call-bind": "^1.0.2"
+      }
+    },
+    "html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
+    },
+    "html2canvas": {
+      "version": "1.0.0-rc.7",
+      "requires": {
+        "css-line-break": "1.1.1"
+      }
+    },
+    "htmlescape": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+      "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=",
+      "dev": true
+    },
+    "htmlparser2": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.0.tgz",
+      "integrity": "sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.0.0",
+        "domutils": "^2.4.4",
+        "entities": "^2.0.0"
+      }
+    },
+    "http-cache-semantics": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+      "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
+      "dev": true
+    },
+    "http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "http-proxy": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "^4.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "human-signals": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+      "dev": true
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "icss-utils": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
+      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="
+    },
+    "ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+    },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "dev": true
+    },
+    "image-minimizer-webpack-plugin": {
+      "version": "2.2.0",
+      "dev": true,
+      "requires": {
+        "imagemin": "^7.0.1",
+        "klona": "^2.0.4",
+        "p-limit": "^3.1.0",
+        "schema-utils": "^3.0.0",
+        "serialize-javascript": "^5.0.1"
+      }
+    },
+    "imagemin": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-7.0.1.tgz",
+      "integrity": "sha512-33AmZ+xjZhg2JMCe+vDf6a9mzWukE7l+wAtesjE7KyteqqKjzxv7aVQeWnul1Ve26mWvEQqyPwl0OctNBfSR9w==",
+      "dev": true,
+      "requires": {
+        "file-type": "^12.0.0",
+        "globby": "^10.0.0",
+        "graceful-fs": "^4.2.2",
+        "junk": "^3.1.0",
+        "make-dir": "^3.0.0",
+        "p-pipe": "^3.0.0",
+        "replace-ext": "^1.0.0"
+      },
+      "dependencies": {
+        "file-type": {
+          "version": "12.4.2",
+          "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz",
+          "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==",
+          "dev": true
+        },
+        "globby": {
+          "version": "10.0.2",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+          "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+          "dev": true,
+          "requires": {
+            "@types/glob": "^7.1.1",
+            "array-union": "^2.1.0",
+            "dir-glob": "^3.0.1",
+            "fast-glob": "^3.0.3",
+            "glob": "^7.1.3",
+            "ignore": "^5.1.1",
+            "merge2": "^1.2.3",
+            "slash": "^3.0.0"
+          }
+        },
+        "ignore": {
+          "version": "5.1.8",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+          "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+          "dev": true
+        }
+      }
+    },
+    "imagemin-mozjpeg": {
+      "version": "9.0.0",
+      "dev": true,
+      "requires": {
+        "execa": "^4.0.0",
+        "is-jpg": "^2.0.0",
+        "mozjpeg": "^7.0.0"
+      },
+      "dependencies": {
+        "execa": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+          "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "human-signals": "^1.1.1",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.0",
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          },
+          "dependencies": {
+            "human-signals": {
+              "version": "1.1.1",
+              "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+              "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+              "dev": true
+            },
+            "onetime": {
+              "version": "5.1.2",
+              "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+              "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+              "dev": true,
+              "requires": {
+                "mimic-fn": "^2.1.0"
+              }
+            },
+            "strip-final-newline": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+              "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+              "dev": true
+            }
+          }
+        },
+        "get-stream": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        }
+      }
+    },
+    "imagemin-optipng": {
+      "version": "8.0.0",
+      "dev": true,
+      "requires": {
+        "exec-buffer": "^3.0.0",
+        "is-png": "^2.0.0",
+        "optipng-bin": "^7.0.0"
+      }
+    },
+    "imagemin-pngquant": {
+      "version": "9.0.1",
+      "dev": true,
+      "requires": {
+        "execa": "^4.0.0",
+        "is-png": "^2.0.0",
+        "is-stream": "^2.0.0",
+        "ow": "^0.17.0",
+        "pngquant-bin": "^6.0.0"
+      },
+      "dependencies": {
+        "execa": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+          "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "human-signals": "^1.1.1",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.0",
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          },
+          "dependencies": {
+            "human-signals": {
+              "version": "1.1.1",
+              "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+              "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+              "dev": true
+            },
+            "onetime": {
+              "version": "5.1.2",
+              "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+              "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+              "dev": true,
+              "requires": {
+                "mimic-fn": "^2.1.0"
+              }
+            },
+            "strip-final-newline": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+              "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+              "dev": true
+            }
+          }
+        },
+        "get-stream": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        }
+      }
+    },
+    "imagemin-svgo": {
+      "version": "8.0.0",
+      "dev": true,
+      "requires": {
+        "is-svg": "^4.2.1",
+        "svgo": "^1.3.2"
+      }
+    },
+    "immutability-helper": {
+      "version": "3.1.1"
+    },
+    "import-fresh": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+      "dev": true,
+      "requires": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      }
+    },
+    "import-lazy": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz",
+      "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==",
+      "dev": true
+    },
+    "import-local": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
+      "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^4.2.0",
+        "resolve-cwd": "^3.0.0"
+      }
+    },
+    "imports-loader": {
+      "version": "2.0.0",
+      "requires": {
+        "loader-utils": "^2.0.0",
+        "source-map": "^0.6.1",
+        "strip-comments": "^2.0.1"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "dev": true,
+      "requires": {
+        "repeating": "^2.0.0"
+      }
+    },
+    "indexes-of": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc="
+    },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+    },
+    "inline-source-map": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
+      "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.5.3"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "insert-module-globals": {
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz",
+      "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "acorn-node": "^1.5.2",
+        "combine-source-map": "^0.8.0",
+        "concat-stream": "^1.6.1",
+        "is-buffer": "^1.1.0",
+        "path-is-absolute": "^1.0.1",
+        "process": "~0.11.0",
+        "through2": "^2.0.0",
+        "undeclared-identifiers": "^1.1.2",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        }
+      }
+    },
+    "internal-slot": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+      "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+      "dev": true,
+      "requires": {
+        "get-intrinsic": "^1.1.0",
+        "has": "^1.0.3",
+        "side-channel": "^1.0.4"
+      }
+    },
+    "interpret": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
+      "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
+      "dev": true
+    },
+    "into-stream": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+      "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
+      "dev": true,
+      "requires": {
+        "from2": "^2.1.1",
+        "p-is-promise": "^1.1.0"
+      }
+    },
+    "invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "requires": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "invert-kv": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+    },
+    "ip-address": {
+      "version": "7.1.0",
+      "requires": {
+        "jsbn": "1.1.0",
+        "sprintf-js": "1.1.2"
+      },
+      "dependencies": {
+        "jsbn": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+          "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA="
+        }
+      }
+    },
+    "is-absolute-url": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+      "dev": true
+    },
+    "is-any-array": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-0.1.1.tgz",
+      "integrity": "sha512-qTiELO+kpTKqPgxPYbshMERlzaFu29JDnpB8s3bjg+JkxBpw29/qqSaOdKv2pCdaG92rLGeG/zG2GauX58hfoA=="
+    },
+    "is-arguments": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz",
+      "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0"
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-boolean-object": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz",
+      "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+      "dev": true
+    },
+    "is-callable": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+      "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+      "dev": true
+    },
+    "is-color-stop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
+      "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
+      "dev": true,
+      "requires": {
+        "css-color-names": "^0.0.4",
+        "hex-color-regex": "^1.1.0",
+        "hsl-regex": "^1.0.0",
+        "hsla-regex": "^1.0.0",
+        "rgb-regex": "^1.0.1",
+        "rgba-regex": "^1.0.0"
+      }
+    },
+    "is-core-module": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
+      "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+      "dev": true
+    },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
+    "is-docker": {
+      "version": "2.1.1",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
+      "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w=="
+    },
+    "is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "dev": true
+    },
+    "is-generator-function": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz",
+      "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-jpg": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz",
+      "integrity": "sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=",
+      "dev": true
+    },
+    "is-natural-number": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
+      "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg="
+    },
+    "is-negative-zero": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+      "dev": true
+    },
+    "is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true
+    },
+    "is-number-object": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
+      "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==",
+      "dev": true
+    },
+    "is-obj": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+      "dev": true
+    },
+    "is-object": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+      "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA=="
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-png": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-png/-/is-png-2.0.0.tgz",
+      "integrity": "sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==",
+      "dev": true
+    },
+    "is-redirect": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+      "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
+    },
+    "is-regex": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz",
+      "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-retry-allowed": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+    },
+    "is-string": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+      "dev": true
+    },
+    "is-subset": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+      "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
+      "dev": true
+    },
+    "is-svg": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.2.1.tgz",
+      "integrity": "sha512-PHx3ANecKsKNl5y5+Jvt53Y4J7MfMpbNZkv384QNiswMKAWIbvcqbPz+sYbFKJI8Xv3be01GSFniPmoaP+Ai5A==",
+      "dev": true,
+      "requires": {
+        "html-comment-regex": "^1.1.2"
+      }
+    },
+    "is-symbol": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+      "dev": true,
+      "requires": {
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "is-typed-array": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz",
+      "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==",
+      "dev": true,
+      "requires": {
+        "available-typed-arrays": "^1.0.2",
+        "call-bind": "^1.0.2",
+        "es-abstract": "^1.18.0-next.2",
+        "foreach": "^2.0.5",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+    },
+    "isbinaryfile": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz",
+      "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "istanbul-instrumenter-loader": {
+      "version": "3.0.1",
+      "requires": {
+        "convert-source-map": "^1.5.0",
+        "istanbul-lib-instrument": "^1.7.3",
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^0.3.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "requires": {
+            "co": "^4.6.0",
+            "fast-deep-equal": "^1.0.0",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.3.0"
+          },
+          "dependencies": {
+            "co": {
+              "version": "4.6.0",
+              "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+              "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+            }
+          }
+        },
+        "fast-deep-equal": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+          "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
+        },
+        "json-schema-traverse": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+        },
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "1.0.1",
+              "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+              "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+              "requires": {
+                "minimist": "^1.2.0"
+              }
+            }
+          }
+        },
+        "schema-utils": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
+          "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
+          "requires": {
+            "ajv": "^5.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-coverage": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg=="
+    },
+    "istanbul-lib-instrument": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz",
+      "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==",
+      "requires": {
+        "babel-generator": "^6.18.0",
+        "babel-template": "^6.16.0",
+        "babel-traverse": "^6.18.0",
+        "babel-types": "^6.18.0",
+        "babylon": "^6.18.0",
+        "istanbul-lib-coverage": "^1.2.1",
+        "semver": "^5.3.0"
+      },
+      "dependencies": {
+        "istanbul-lib-coverage": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz",
+          "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ=="
+        }
+      }
+    },
+    "istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+      "requires": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^3.0.0",
+        "supports-color": "^7.1.0"
+      }
+    },
+    "istanbul-lib-source-maps": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+      "requires": {
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^3.0.0",
+        "source-map": "^0.6.1"
+      }
+    },
+    "istanbul-reports": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+      "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+      "requires": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      }
+    },
+    "isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "requires": {
+        "has-to-string-tag-x": "^1.2.0",
+        "is-object": "^1.0.1"
+      }
+    },
+    "jasmine-core": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz",
+      "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==",
+      "dev": true
+    },
+    "jasmine-enzyme": {
+      "version": "7.1.2",
+      "dev": true,
+      "requires": {
+        "enzyme-matchers": "^7.1.2"
+      }
+    },
+    "jest-worker": {
+      "version": "26.6.2",
+      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+      "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "merge-stream": "^2.0.0",
+        "supports-color": "^7.0.0"
+      }
+    },
+    "js-string-escape": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
+      "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=",
+      "dev": true
+    },
+    "js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "js-yaml": {
+      "version": "3.14.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+    },
+    "json-bignumber": {
+      "version": "1.0.2",
+      "requires": {
+        "bignumber.js": "^7.2.1"
+      },
+      "dependencies": {
+        "bignumber.js": {
+          "version": "7.2.1",
+          "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
+          "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ=="
+        }
+      }
+    },
+    "json-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+      "dev": true
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json5": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "jsonparse": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "jsx-ast-utils": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
+      "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.1.2",
+        "object.assign": "^4.1.2"
+      }
+    },
+    "junk": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
+      "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
+      "dev": true
+    },
+    "karma": {
+      "version": "6.1.0",
+      "dev": true,
+      "requires": {
+        "body-parser": "^1.19.0",
+        "braces": "^3.0.2",
+        "chokidar": "^3.4.2",
+        "colors": "^1.4.0",
+        "connect": "^3.7.0",
+        "di": "^0.0.1",
+        "dom-serialize": "^2.2.1",
+        "glob": "^7.1.6",
+        "graceful-fs": "^4.2.4",
+        "http-proxy": "^1.18.1",
+        "isbinaryfile": "^4.0.6",
+        "lodash": "^4.17.19",
+        "log4js": "^6.2.1",
+        "mime": "^2.4.5",
+        "minimatch": "^3.0.4",
+        "qjobs": "^1.2.0",
+        "range-parser": "^1.2.1",
+        "rimraf": "^3.0.2",
+        "socket.io": "^3.1.0",
+        "source-map": "^0.6.1",
+        "tmp": "0.2.1",
+        "ua-parser-js": "^0.7.23",
+        "yargs": "^16.1.1"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        }
+      }
+    },
+    "karma-babel-preprocessor": {
+      "version": "8.0.1",
+      "dev": true
+    },
+    "karma-browserify": {
+      "version": "8.0.0",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "^1.1.3",
+        "hat": "^0.0.3",
+        "js-string-escape": "^1.0.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.0",
+        "os-shim": "^0.1.3"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        }
+      }
+    },
+    "karma-chrome-launcher": {
+      "version": "3.1.0",
+      "dev": true,
+      "requires": {
+        "which": "^1.2.1"
+      }
+    },
+    "karma-coverage": {
+      "version": "2.0.3",
+      "requires": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "istanbul-lib-instrument": "^4.0.1",
+        "istanbul-lib-report": "^3.0.0",
+        "istanbul-lib-source-maps": "^4.0.0",
+        "istanbul-reports": "^3.0.0",
+        "minimatch": "^3.0.4"
+      },
+      "dependencies": {
+        "istanbul-lib-instrument": {
+          "version": "4.0.3",
+          "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+          "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+          "requires": {
+            "@babel/core": "^7.7.5",
+            "@istanbuljs/schema": "^0.1.2",
+            "istanbul-lib-coverage": "^3.0.0",
+            "semver": "^6.3.0"
+          },
+          "dependencies": {
+            "@babel/core": {
+              "version": "7.12.13",
+              "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.13.tgz",
+              "integrity": "sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw==",
+              "requires": {
+                "@babel/code-frame": "^7.12.13",
+                "@babel/generator": "^7.12.13",
+                "@babel/helper-module-transforms": "^7.12.13",
+                "@babel/helpers": "^7.12.13",
+                "@babel/parser": "^7.12.13",
+                "@babel/template": "^7.12.13",
+                "@babel/traverse": "^7.12.13",
+                "@babel/types": "^7.12.13",
+                "convert-source-map": "^1.7.0",
+                "debug": "^4.1.0",
+                "gensync": "^1.0.0-beta.1",
+                "json5": "^2.1.2",
+                "lodash": "^4.17.19",
+                "semver": "^5.4.1",
+                "source-map": "^0.5.0"
+              },
+              "dependencies": {
+                "semver": {
+                  "version": "5.7.1",
+                  "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+                  "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+                }
+              }
+            },
+            "@istanbuljs/schema": {
+              "version": "0.1.3",
+              "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+              "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA=="
+            }
+          }
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+        }
+      }
+    },
+    "karma-jasmine": {
+      "version": "4.0.1",
+      "dev": true,
+      "requires": {
+        "jasmine-core": "^3.6.0"
+      }
+    },
+    "karma-jasmine-html-reporter": {
+      "version": "1.5.4",
+      "dev": true
+    },
+    "karma-requirejs": {
+      "version": "1.1.0",
+      "dev": true
+    },
+    "karma-source-map-support": {
+      "version": "1.4.0",
+      "dev": true,
+      "requires": {
+        "source-map-support": "^0.5.5"
+      }
+    },
+    "karma-sourcemap-loader": {
+      "version": "0.3.8",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2"
+      }
+    },
+    "karma-webpack": {
+      "version": "5.0.0",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3",
+        "minimatch": "^3.0.4",
+        "webpack-merge": "^4.1.5"
+      }
+    },
+    "keyv": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
+      "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
+      "dev": true,
+      "requires": {
+        "json-buffer": "3.0.0"
+      }
+    },
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true
+    },
+    "klona": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
+      "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
+      "dev": true
+    },
+    "labeled-stream-splicer": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz",
+      "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "stream-splicer": "^2.0.0"
+      }
+    },
+    "lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "requires": {
+        "invert-kv": "^1.0.0"
+      }
+    },
+    "leaflet": {
+      "version": "1.7.1"
+    },
+    "levn": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
+      }
+    },
+    "lines-and-columns": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "dev": true
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^2.2.0",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0",
+        "strip-bom": "^2.0.0"
+      },
+      "dependencies": {
+        "parse-json": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.2.0"
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "loader-runner": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
+      "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+      "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+          "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+          "requires": {
+            "minimist": "^1.2.5"
+          }
+        }
+      }
+    },
+    "locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "requires": {
+        "p-locate": "^4.1.0"
+      }
+    },
+    "lodash._baseisequal": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz",
+      "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=",
+      "dev": true,
+      "requires": {
+        "lodash.isarray": "^3.0.0",
+        "lodash.istypedarray": "^3.0.0",
+        "lodash.keys": "^3.0.0"
+      }
+    },
+    "lodash._bindcallback": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
+      "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
+      "dev": true
+    },
+    "lodash._getnative": {
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
+      "dev": true
+    },
+    "lodash.escape": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
+      "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=",
+      "dev": true
+    },
+    "lodash.flattendeep": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
+      "dev": true
+    },
+    "lodash.isarguments": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
+      "dev": true
+    },
+    "lodash.isarray": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
+      "dev": true
+    },
+    "lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+      "dev": true
+    },
+    "lodash.istypedarray": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz",
+      "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=",
+      "dev": true
+    },
+    "lodash.keys": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+      "dev": true,
+      "requires": {
+        "lodash._getnative": "^3.0.0",
+        "lodash.isarguments": "^3.0.0",
+        "lodash.isarray": "^3.0.0"
+      }
+    },
+    "lodash.memoize": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+      "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=",
+      "dev": true
+    },
+    "lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+      "dev": true
+    },
+    "log4js": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
+      "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==",
+      "dev": true,
+      "requires": {
+        "date-format": "^3.0.0",
+        "debug": "^4.1.1",
+        "flatted": "^2.0.1",
+        "rfdc": "^1.1.4",
+        "streamroller": "^2.2.4"
+      }
+    },
+    "logalot": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz",
+      "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=",
+      "dev": true,
+      "requires": {
+        "figures": "^1.3.5",
+        "squeak": "^1.0.0"
+      }
+    },
+    "longest": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+      "dev": true
+    },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "dev": true,
+      "requires": {
+        "currently-unhandled": "^0.4.1",
+        "signal-exit": "^3.0.0"
+      }
+    },
+    "lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
+    },
+    "lpad-align": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz",
+      "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^4.0.1",
+        "indent-string": "^2.1.0",
+        "longest": "^1.0.0",
+        "meow": "^3.3.0"
+      }
+    },
+    "lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "requires": {
+        "yallist": "^4.0.0"
+      }
+    },
+    "lunr": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/lunr/-/lunr-0.7.2.tgz",
+      "integrity": "sha1-eaMOky4hbLoWNUHuN6NgfBLNcoE="
+    },
+    "make-dir": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+      "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+      "requires": {
+        "semver": "^6.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+        }
+      }
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "dev": true
+    },
+    "marked": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.9.tgz",
+      "integrity": "sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==",
+      "dev": true
+    },
+    "matches-selector": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/matches-selector/-/matches-selector-0.0.1.tgz",
+      "integrity": "sha1-HfUmIkOuNBwaCATdMCBIJnrHE7s="
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "mdn-data": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
+      "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
+      "dev": true
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "^2.0.0",
+        "decamelize": "^1.1.2",
+        "loud-rejection": "^1.0.0",
+        "map-obj": "^1.0.1",
+        "minimist": "^1.1.3",
+        "normalize-package-data": "^2.3.4",
+        "object-assign": "^4.0.1",
+        "read-pkg-up": "^1.0.1",
+        "redent": "^1.0.0",
+        "trim-newlines": "^1.0.0"
+      }
+    },
+    "merge": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
+      "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ=="
+    },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true
+    },
+    "microbuffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/microbuffer/-/microbuffer-1.0.0.tgz",
+      "integrity": "sha1-izgy7UDIfVH0e7I0kTppinVtGdI=",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+      "dev": true,
+      "requires": {
+        "braces": "^3.0.1",
+        "picomatch": "^2.0.5"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "mime": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz",
+      "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.45.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
+      "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.28",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
+      "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.45.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true
+    },
+    "mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "dev": true
+    },
+    "mini-css-extract-plugin": {
+      "version": "1.3.6",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^2.0.0",
+        "schema-utils": "^3.0.0",
+        "webpack-sources": "^1.1.0"
+      }
+    },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+    },
+    "minipass": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
+      "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
+      "dev": true,
+      "requires": {
+        "yallist": "^4.0.0"
+      }
+    },
+    "minipass-collect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-flush": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-pipeline": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minizlib": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0",
+        "yallist": "^4.0.0"
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "mkdirp-classic": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+      "dev": true
+    },
+    "ml-array-max": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/ml-array-max/-/ml-array-max-1.2.0.tgz",
+      "integrity": "sha512-3UH7XCdjINxbtBWj1EuHMeI242Q3uLuC4rTpSybBWUpGjnG/BefAFxmTolUCuXDM59mJ/G/re80CQbaVIuMjQA==",
+      "requires": {
+        "is-any-array": "^0.1.0"
+      }
+    },
+    "ml-array-min": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/ml-array-min/-/ml-array-min-1.2.0.tgz",
+      "integrity": "sha512-Wgf2+lCndLy1SbeOZSUqlkxD9T1CXPT7CIlNGAZRRQI35wsqvfuNtLNH4qKFx8kNjlq3VGXKOSBHeiXR31vaTA==",
+      "requires": {
+        "is-any-array": "^0.1.0"
+      }
+    },
+    "ml-array-rescale": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-1.3.2.tgz",
+      "integrity": "sha512-kiXwdVCGrer7rLnjR6Q9ZgP6e9rbnmQvYVUMLXyqNg4+zOs+jek8yBupqPZPDr+NvlSE5OuMnfAbP1oA63kHBA==",
+      "requires": {
+        "is-any-array": "^0.1.0",
+        "ml-array-max": "^1.2.0",
+        "ml-array-min": "^1.2.0"
+      }
+    },
+    "ml-matrix": {
+      "version": "6.6.0",
+      "requires": {
+        "ml-array-rescale": "^1.3.2"
+      }
+    },
+    "module-deps": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz",
+      "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.0.3",
+        "browser-resolve": "^2.0.0",
+        "cached-path-relative": "^1.0.2",
+        "concat-stream": "~1.6.0",
+        "defined": "^1.0.0",
+        "detective": "^5.2.0",
+        "duplexer2": "^0.1.2",
+        "inherits": "^2.0.1",
+        "parents": "^1.0.0",
+        "readable-stream": "^2.0.2",
+        "resolve": "^1.4.0",
+        "stream-combiner2": "^1.1.1",
+        "subarg": "^1.0.0",
+        "through2": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "moo": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz",
+      "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==",
+      "dev": true
+    },
+    "mousetrap": {
+      "version": "1.6.5"
+    },
+    "mozjpeg": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-7.0.0.tgz",
+      "integrity": "sha512-mH7atSbIusVTO3A4H43sEdmveN3aWn54k6V0edefzCEvOsTrbjg5murY2TsNznaztWnIgaRbWxeLVp4IgKdedQ==",
+      "dev": true,
+      "requires": {
+        "bin-build": "^3.0.0",
+        "bin-wrapper": "^4.0.0",
+        "logalot": "^2.1.0"
+      }
+    },
+    "ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "nan": {
+      "version": "2.14.2",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+      "dev": true
+    },
+    "nanoid": {
+      "version": "3.1.20",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
+      "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw=="
+    },
+    "nanopop": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.1.0.tgz",
+      "integrity": "sha512-jGTwpFRexSH+fxappnGQtN9dspgE2ipa1aOjtR24igG0pv6JCxImIAmrLRHX+zUF5+1wtsFVbKyfP51kIGAVNw=="
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "nearley": {
+      "version": "2.20.1",
+      "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
+      "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.19.0",
+        "moo": "^0.5.0",
+        "railroad-diagrams": "^1.0.0",
+        "randexp": "0.4.6"
+      }
+    },
+    "neatequal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/neatequal/-/neatequal-1.0.0.tgz",
+      "integrity": "sha1-LuEhG8n6bkxVcV/SELsFYC6xrjs=",
+      "dev": true,
+      "requires": {
+        "varstream": "^0.3.2"
+      }
+    },
+    "negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "dev": true
+    },
+    "neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true
+    },
+    "next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "node-gyp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz",
+      "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.0.3",
+        "graceful-fs": "^4.1.2",
+        "mkdirp": "^0.5.0",
+        "nopt": "2 || 3",
+        "npmlog": "0 || 1 || 2 || 3 || 4",
+        "osenv": "0",
+        "request": "^2.87.0",
+        "rimraf": "2",
+        "semver": "~5.3.0",
+        "tar": "^4.4.8",
+        "which": "1"
+      },
+      "dependencies": {
+        "chownr": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+          "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+          "dev": true
+        },
+        "fs-minipass": {
+          "version": "1.2.7",
+          "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+          "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+          "dev": true,
+          "requires": {
+            "minipass": "^2.6.0"
+          }
+        },
+        "minipass": {
+          "version": "2.9.0",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+          "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "^5.1.2",
+            "yallist": "^3.0.0"
+          }
+        },
+        "minizlib": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+          "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+          "dev": true,
+          "requires": {
+            "minipass": "^2.9.0"
+          }
+        },
+        "rimraf": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+          "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "semver": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+          "dev": true
+        },
+        "tar": {
+          "version": "4.4.13",
+          "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+          "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+          "dev": true,
+          "requires": {
+            "chownr": "^1.1.1",
+            "fs-minipass": "^1.2.5",
+            "minipass": "^2.8.6",
+            "minizlib": "^1.2.1",
+            "mkdirp": "^0.5.0",
+            "safe-buffer": "^5.1.2",
+            "yallist": "^3.0.3"
+          }
+        },
+        "yallist": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+          "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+          "dev": true
+        }
+      }
+    },
+    "node-releases": {
+      "version": "1.1.70",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz",
+      "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==",
+      "dev": true
+    },
+    "nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "dev": true,
+      "requires": {
+        "abbrev": "1"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true
+    },
+    "normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "dev": true
+    },
+    "normalize-url": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+      "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
+      "dev": true
+    },
+    "npm-conf": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+      "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+      "requires": {
+        "config-chain": "^1.1.11",
+        "pify": "^3.0.0"
+      }
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "^2.0.0"
+      }
+    },
+    "npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "dev": true,
+      "requires": {
+        "are-we-there-yet": "~1.1.2",
+        "console-control-strings": "~1.1.0",
+        "gauge": "~2.7.3",
+        "set-blocking": "~2.0.0"
+      }
+    },
+    "nth-check": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+      "dev": true,
+      "requires": {
+        "boolbase": "~1.0.0"
+      }
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+    },
+    "nw": {
+      "version": "0.51.1",
+      "resolved": "https://registry.npmjs.org/nw/-/nw-0.51.1.tgz",
+      "integrity": "sha512-wKU/f0dtPeVVSa+kRqFlpxxwvRc979Jzcav46JetltGTk/5/sBhgxEjPuDgy5LrdSKLdTL/FQiqGUMAd9pFE6g==",
+      "requires": {
+        "chalk": "~1.1.3",
+        "decompress": "^4.2.0",
+        "download": "^5.0.3",
+        "file-exists": "^2.0.0",
+        "merge": "^1.2.0",
+        "progress": "^2.0.3",
+        "rimraf": "^2.2.8",
+        "semver": "^5.1.0",
+        "yargs": "^3.2.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+        },
+        "camelcase": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+          "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "requires": {
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
+          }
+        },
+        "cliui": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+          "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+          "requires": {
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1",
+            "wrap-ansi": "^2.0.0"
+          }
+        },
+        "download": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/download/-/download-5.0.3.tgz",
+          "integrity": "sha1-Y1N/l3+ZJmow64oqL70fILgAD3o=",
+          "requires": {
+            "caw": "^2.0.0",
+            "decompress": "^4.0.0",
+            "filenamify": "^2.0.0",
+            "get-stream": "^3.0.0",
+            "got": "^6.3.0",
+            "mkdirp": "^0.5.1",
+            "pify": "^2.3.0"
+          }
+        },
+        "got": {
+          "version": "6.7.1",
+          "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
+          "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+          "requires": {
+            "create-error-class": "^3.0.0",
+            "duplexer3": "^0.1.4",
+            "get-stream": "^3.0.0",
+            "is-redirect": "^1.0.0",
+            "is-retry-allowed": "^1.0.0",
+            "is-stream": "^1.0.0",
+            "lowercase-keys": "^1.0.0",
+            "safe-buffer": "^5.0.1",
+            "timed-out": "^4.0.0",
+            "unzip-response": "^2.0.1",
+            "url-parse-lax": "^1.0.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+        },
+        "rimraf": {
+          "version": "2.7.1",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+          "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+        },
+        "wrap-ansi": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+          "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+          "requires": {
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1"
+          }
+        },
+        "y18n": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
+          "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ=="
+        },
+        "yargs": {
+          "version": "3.32.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+          "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
+          "requires": {
+            "camelcase": "^2.0.1",
+            "cliui": "^3.0.3",
+            "decamelize": "^1.1.1",
+            "os-locale": "^1.4.0",
+            "string-width": "^1.0.1",
+            "window-size": "^0.1.4",
+            "y18n": "^3.2.0"
+          }
+        }
+      }
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
+    "object-inspect": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
+      "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
+      "dev": true
+    },
+    "object-is": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz",
+      "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
+      }
+    },
+    "object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+      "dev": true
+    },
+    "object.assign": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "has-symbols": "^1.0.1",
+        "object-keys": "^1.1.1"
+      }
+    },
+    "object.entries": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz",
+      "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "has": "^1.0.3"
+      }
+    },
+    "object.fromentries": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz",
+      "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "has": "^1.0.3"
+      }
+    },
+    "object.getownpropertydescriptors": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz",
+      "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "object.values": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz",
+      "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "has": "^1.0.3"
+      }
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "^2.1.0"
+      }
+    },
+    "opener": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+      "dev": true
+    },
+    "optionator": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "dev": true,
+      "requires": {
+        "deep-is": "^0.1.3",
+        "fast-levenshtein": "^2.0.6",
+        "levn": "^0.4.1",
+        "prelude-ls": "^1.2.1",
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.3"
+      }
+    },
+    "optipng-bin": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-7.0.0.tgz",
+      "integrity": "sha512-mesUAwfedu5p9gRQwlYgD6Svw5IH3VUIWDJj/9cNpP3yFNbbEVqkTMWYhrIEn/cxmbGA3LpZrdoV2Yl8OfmnIA==",
+      "dev": true,
+      "requires": {
+        "bin-build": "^3.0.0",
+        "bin-wrapper": "^4.0.0",
+        "logalot": "^2.0.0"
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "os-filter-obj": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz",
+      "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==",
+      "dev": true,
+      "requires": {
+        "arch": "^2.1.0"
+      }
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-locale": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "requires": {
+        "lcid": "^1.0.0"
+      }
+    },
+    "os-shim": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz",
+      "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=",
+      "dev": true
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "osenv": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+      "dev": true,
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.0"
+      }
+    },
+    "ow": {
+      "version": "0.17.0",
+      "resolved": "https://registry.npmjs.org/ow/-/ow-0.17.0.tgz",
+      "integrity": "sha512-i3keDzDQP5lWIe4oODyDFey1qVrq2hXKTuTH2VpqwpYtzPiKZt2ziRI4NBQmgW40AnV5Euz17OyWweCb+bNEQA==",
+      "dev": true,
+      "requires": {
+        "type-fest": "^0.11.0"
+      }
+    },
+    "p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
+      "dev": true
+    },
+    "p-event": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz",
+      "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=",
+      "dev": true,
+      "requires": {
+        "p-timeout": "^1.1.1"
+      }
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "p-is-promise": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "dev": true,
+      "requires": {
+        "yocto-queue": "^0.1.0"
+      }
+    },
+    "p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "requires": {
+        "p-limit": "^2.2.0"
+      },
+      "dependencies": {
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        }
+      }
+    },
+    "p-map": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+      "dev": true,
+      "requires": {
+        "aggregate-error": "^3.0.0"
+      }
+    },
+    "p-map-series": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz",
+      "integrity": "sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco=",
+      "dev": true,
+      "requires": {
+        "p-reduce": "^1.0.0"
+      }
+    },
+    "p-pipe": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz",
+      "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==",
+      "dev": true
+    },
+    "p-reduce": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
+      "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
+      "dev": true
+    },
+    "p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "dev": true,
+      "requires": {
+        "p-finally": "^1.0.0"
+      }
+    },
+    "p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true
+    },
+    "pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+      "dev": true
+    },
+    "parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0"
+      }
+    },
+    "parents": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+      "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=",
+      "dev": true,
+      "requires": {
+        "path-platform": "~0.11.15"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+      "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+      "dev": true,
+      "requires": {
+        "asn1.js": "^5.2.0",
+        "browserify-aes": "^1.0.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "parse-json": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      }
+    },
+    "parse5": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+      "dev": true
+    },
+    "parse5-htmlparser2-tree-adapter": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+      "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+      "dev": true,
+      "requires": {
+        "parse5": "^6.0.1"
+      }
+    },
+    "parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "dev": true
+    },
+    "path-platform": {
+      "version": "0.11.15",
+      "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+      "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true
+    },
+    "pathfinding": {
+      "version": "0.4.18",
+      "requires": {
+        "heap": "0.2.5"
+      }
+    },
+    "paths-js": {
+      "version": "0.4.11"
+    },
+    "pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "requires": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true
+    },
+    "pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "requires": {
+        "pinkie": "^2.0.0"
+      }
+    },
+    "pkg-dir": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+      "dev": true,
+      "requires": {
+        "find-up": "^4.0.0"
+      }
+    },
+    "pngquant-bin": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-6.0.0.tgz",
+      "integrity": "sha512-oXWAS9MQ9iiDAJRdAZ9KO1mC5UwhzKkJsmetiu0iqIjJuW7JsuLhmc4JdRm7uJkIWRzIAou/Vq2VcjfJwz30Ow==",
+      "dev": true,
+      "requires": {
+        "bin-build": "^3.0.0",
+        "bin-wrapper": "^4.0.1",
+        "execa": "^4.0.0",
+        "logalot": "^2.0.0"
+      },
+      "dependencies": {
+        "execa": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+          "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "human-signals": "^1.1.1",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.0",
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        }
+      }
+    },
+    "popper.js": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+      "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
+    },
+    "postcss-calc": {
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz",
+      "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.27",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.0.2"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-colormin": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
+      "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "color": "^3.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-convert-values": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz",
+      "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-discard-comments": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz",
+      "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-discard-duplicates": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz",
+      "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-discard-empty": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz",
+      "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-discard-overridden": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz",
+      "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-loader": {
+      "version": "5.0.0",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^7.0.0",
+        "klona": "^2.0.4",
+        "semver": "^7.3.4"
+      },
+      "dependencies": {
+        "cosmiconfig": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+          "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
+          "dev": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.2.1",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.10.0"
+          }
+        },
+        "semver": {
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        }
+      }
+    },
+    "postcss-merge-longhand": {
+      "version": "4.0.11",
+      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
+      "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==",
+      "dev": true,
+      "requires": {
+        "css-color-names": "0.0.4",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0",
+        "stylehacks": "^4.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-merge-rules": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz",
+      "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-api": "^3.0.0",
+        "cssnano-util-same-parent": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-selector-parser": "^3.0.0",
+        "vendors": "^1.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-selector-parser": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+          "dev": true,
+          "requires": {
+            "dot-prop": "^5.2.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-minify-font-values": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz",
+      "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-minify-gradients": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz",
+      "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "is-color-stop": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-minify-params": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz",
+      "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "^1.0.0",
+        "browserslist": "^4.0.0",
+        "cssnano-util-get-arguments": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0",
+        "uniqs": "^2.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-minify-selectors": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz",
+      "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "^1.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-selector-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-selector-parser": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+          "dev": true,
+          "requires": {
+            "dot-prop": "^5.2.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-extract-imports": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
+      "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw=="
+    },
+    "postcss-modules-local-by-default": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
+      "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
+      "requires": {
+        "icss-utils": "^5.0.0",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.1.0"
+      },
+      "dependencies": {
+        "postcss-selector-parser": {
+          "version": "6.0.4",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz",
+          "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==",
+          "requires": {
+            "cssesc": "^3.0.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1",
+            "util-deprecate": "^1.0.2"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+          "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
+        }
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
+      "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
+      "requires": {
+        "postcss-selector-parser": "^6.0.4"
+      },
+      "dependencies": {
+        "postcss-selector-parser": {
+          "version": "6.0.4",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz",
+          "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==",
+          "requires": {
+            "cssesc": "^3.0.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1",
+            "util-deprecate": "^1.0.2"
+          }
+        }
+      }
+    },
+    "postcss-modules-values": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+      "requires": {
+        "icss-utils": "^5.0.0"
+      }
+    },
+    "postcss-normalize-charset": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
+      "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-display-values": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz",
+      "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-match": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-positions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz",
+      "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-repeat-style": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz",
+      "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "cssnano-util-get-match": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-string": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz",
+      "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-timing-functions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz",
+      "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-match": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-unicode": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz",
+      "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-url": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz",
+      "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==",
+      "dev": true,
+      "requires": {
+        "is-absolute-url": "^2.0.0",
+        "normalize-url": "^3.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-whitespace": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz",
+      "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-ordered-values": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz",
+      "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-reduce-initial": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz",
+      "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-api": "^3.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-reduce-transforms": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz",
+      "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-match": "^4.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-selector-parser": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz",
+      "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==",
+      "dev": true,
+      "requires": {
+        "cssesc": "^3.0.0",
+        "indexes-of": "^1.0.1",
+        "uniq": "^1.0.1",
+        "util-deprecate": "^1.0.2"
+      }
+    },
+    "postcss-svgo": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz",
+      "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==",
+      "dev": true,
+      "requires": {
+        "is-svg": "^3.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0",
+        "svgo": "^1.0.0"
+      },
+      "dependencies": {
+        "is-svg": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
+          "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
+          "dev": true,
+          "requires": {
+            "html-comment-regex": "^1.1.0"
+          }
+        },
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-unique-selectors": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz",
+      "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "^1.0.0",
+        "postcss": "^7.0.0",
+        "uniqs": "^2.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-value-parser": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+      "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
+      "dev": true
+    },
+    "precond": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
+      "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw="
+    },
+    "prelude-ls": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+      "dev": true
+    },
+    "prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+    },
+    "progress": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
+    },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "dev": true
+    },
+    "prop-types": {
+      "version": "15.7.2",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "requires": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.8.1"
+      }
+    },
+    "prop-types-exact": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz",
+      "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3",
+        "object.assign": "^4.1.0",
+        "reflect.ownkeys": "^0.2.0"
+      }
+    },
+    "proto-list": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+      "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk="
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+    },
+    "q": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+      "dev": true
+    },
+    "qjobs": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+      "dev": true
+    },
+    "query-string": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+      "dev": true,
+      "requires": {
+        "decode-uri-component": "^0.2.0",
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      }
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "queue-microtask": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz",
+      "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==",
+      "dev": true
+    },
+    "railroad-diagrams": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+      "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=",
+      "dev": true
+    },
+    "randexp": {
+      "version": "0.4.6",
+      "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+      "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
+      "dev": true,
+      "requires": {
+        "discontinuous-range": "1.0.0",
+        "ret": "~0.1.10"
+      }
+    },
+    "randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true
+    },
+    "raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      }
+    },
+    "react": {
+      "version": "16.14.0",
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.1",
+        "prop-types": "^15.6.2"
+      }
+    },
+    "react-dom": {
+      "version": "16.14.0",
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.1",
+        "prop-types": "^15.6.2",
+        "scheduler": "^0.19.1"
+      }
+    },
+    "react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+    },
+    "react-test-renderer": {
+      "version": "16.14.0",
+      "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz",
+      "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "prop-types": "^15.6.2",
+        "react-is": "^16.8.6",
+        "scheduler": "^0.19.1"
+      }
+    },
+    "read-only-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+      "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "^1.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^1.0.0"
+      },
+      "dependencies": {
+        "path-type": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+          "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "dev": true,
+      "requires": {
+        "find-up": "^1.0.0",
+        "read-pkg": "^1.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "^2.0.0"
+          }
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "readdirp": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+      "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+      "dev": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "rechoir": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz",
+      "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==",
+      "dev": true,
+      "requires": {
+        "resolve": "^1.9.0"
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "dev": true,
+      "requires": {
+        "indent-string": "^2.1.0",
+        "strip-indent": "^1.0.1"
+      }
+    },
+    "reflect.ownkeys": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
+      "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=",
+      "dev": true
+    },
+    "regenerate": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+      "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+      "dev": true
+    },
+    "regenerate-unicode-properties": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+      "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0"
+      }
+    },
+    "regenerator-runtime": {
+      "version": "0.13.7",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+      "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
+      "dev": true
+    },
+    "regenerator-transform": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+      "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.8.4"
+      }
+    },
+    "regex-parser": {
+      "version": "2.2.11",
+      "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz",
+      "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==",
+      "dev": true
+    },
+    "regexp.prototype.flags": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz",
+      "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3"
+      }
+    },
+    "regexpp": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+      "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+      "dev": true
+    },
+    "regexpu-core": {
+      "version": "4.7.1",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
+      "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0",
+        "regenerate-unicode-properties": "^8.2.0",
+        "regjsgen": "^0.5.1",
+        "regjsparser": "^0.6.4",
+        "unicode-match-property-ecmascript": "^1.0.4",
+        "unicode-match-property-value-ecmascript": "^1.2.0"
+      }
+    },
+    "regjsgen": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+      "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
+      "dev": true
+    },
+    "regjsparser": {
+      "version": "0.6.7",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.7.tgz",
+      "integrity": "sha512-ib77G0uxsA2ovgiYbCVGx4Pv3PSttAx2vIwidqQzbL2U5S4Q+j00HdSAneSBuyVcMvEnTXMjiGgB+DlXozVhpQ==",
+      "dev": true,
+      "requires": {
+        "jsesc": "~0.5.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        }
+      }
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "requires": {
+        "is-finite": "^1.0.0"
+      }
+    },
+    "replace-ext": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
+      "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
+      "dev": true
+    },
+    "request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "dependencies": {
+        "qs": {
+          "version": "6.5.2",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+          "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+          "dev": true
+        }
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true
+    },
+    "requirejs": {
+      "version": "2.3.6"
+    },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+      "dev": true
+    },
+    "resize-observer-polyfill": {
+      "version": "1.5.1",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+      "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+      "dev": true,
+      "requires": {
+        "is-core-module": "^2.1.0",
+        "path-parse": "^1.0.6"
+      }
+    },
+    "resolve-cwd": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+      "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^5.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+          "dev": true
+        }
+      }
+    },
+    "resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "resolve-url-loader": {
+      "version": "3.1.2",
+      "dev": true,
+      "requires": {
+        "adjust-sourcemap-loader": "3.0.0",
+        "camelcase": "5.3.1",
+        "compose-function": "3.0.3",
+        "convert-source-map": "1.7.0",
+        "es6-iterator": "2.0.3",
+        "loader-utils": "1.2.3",
+        "postcss": "7.0.21",
+        "rework": "1.0.1",
+        "rework-visit": "1.0.0",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "emojis-list": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+          "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+          "dev": true
+        },
+        "loader-utils": {
+          "version": "1.2.3",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+          "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^2.0.0",
+            "json5": "^1.0.1"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "1.0.1",
+              "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+              "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+              "dev": true,
+              "requires": {
+                "minimist": "^1.2.0"
+              }
+            }
+          }
+        },
+        "postcss": {
+          "version": "7.0.21",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz",
+          "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "responselike": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+      "dev": true,
+      "requires": {
+        "lowercase-keys": "^1.0.0"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true
+    },
+    "rework": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
+      "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "^0.3.3",
+        "css": "^2.0.0"
+      },
+      "dependencies": {
+        "convert-source-map": {
+          "version": "0.3.5",
+          "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
+          "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=",
+          "dev": true
+        }
+      }
+    },
+    "rework-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz",
+      "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=",
+      "dev": true
+    },
+    "rfdc": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.2.0.tgz",
+      "integrity": "sha512-ijLyszTMmUrXvjSooucVQwimGUk84eRcmCuLV8Xghe3UO85mjUtRAHRyoMM6XtyqbECaXuBWx18La3523sXINA==",
+      "dev": true
+    },
+    "rgb-regex": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
+      "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
+      "dev": true
+    },
+    "rgba-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
+      "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "rst-selector-parser": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz",
+      "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=",
+      "dev": true,
+      "requires": {
+        "lodash.flattendeep": "^4.4.0",
+        "nearley": "^2.7.10"
+      }
+    },
+    "run-parallel": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+      "dev": true,
+      "requires": {
+        "queue-microtask": "^1.2.2"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "sass": {
+      "version": "1.32.7",
+      "dev": true,
+      "requires": {
+        "chokidar": ">=2.0.0 <4.0.0"
+      }
+    },
+    "sass-loader": {
+      "version": "11.0.1",
+      "dev": true,
+      "requires": {
+        "klona": "^2.0.4",
+        "neo-async": "^2.6.2"
+      }
+    },
+    "sass-resources-loader": {
+      "version": "2.1.1",
+      "dev": true,
+      "requires": {
+        "async": "^3.2.0",
+        "chalk": "^4.1.0",
+        "glob": "^7.1.6",
+        "loader-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+          "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        }
+      }
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+      "dev": true
+    },
+    "scheduler": {
+      "version": "0.19.1",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
+      "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.1"
+      }
+    },
+    "schema-utils": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
+      "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
+      "requires": {
+        "@types/json-schema": "^7.0.6",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      }
+    },
+    "seek-bzip": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+      "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
+      "requires": {
+        "commander": "^2.8.1"
+      }
+    },
+    "select2": {
+      "version": "4.0.13"
+    },
+    "semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+    },
+    "semver-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
+      "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
+      "dev": true
+    },
+    "semver-truncate": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz",
+      "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=",
+      "dev": true,
+      "requires": {
+        "semver": "^5.3.0"
+      }
+    },
+    "serialize-javascript": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
+      "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.1.0"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "shallow-clone": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^6.0.2"
+      }
+    },
+    "shasum-object": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz",
+      "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==",
+      "dev": true,
+      "requires": {
+        "fast-safe-stringify": "^2.0.7"
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "shell-quote": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+      "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
+      "dev": true
+    },
+    "shim-loader": {
+      "version": "1.0.1",
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "lodash": "^4.14.1",
+        "precond": "^0.2.3",
+        "webpack-sources": "^0.2.3"
+      },
+      "dependencies": {
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "1.0.1",
+              "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+              "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+              "requires": {
+                "minimist": "^1.2.0"
+              }
+            }
+          }
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        },
+        "source-list-map": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz",
+          "integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE="
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+        },
+        "webpack-sources": {
+          "version": "0.2.3",
+          "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz",
+          "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=",
+          "requires": {
+            "source-list-map": "^1.1.1",
+            "source-map": "~0.5.3"
+          }
+        }
+      }
+    },
+    "side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      }
+    },
+    "signal-exit": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "dev": true
+    },
+    "simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "dev": true
+    },
+    "simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.3.1"
+      },
+      "dependencies": {
+        "is-arrayish": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+          "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+          "dev": true
+        }
+      }
+    },
+    "sirv": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.11.tgz",
+      "integrity": "sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg==",
+      "dev": true,
+      "requires": {
+        "@polka/url": "^1.0.0-next.9",
+        "mime": "^2.3.1",
+        "totalist": "^1.0.0"
+      }
+    },
+    "slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true
+    },
+    "slice-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      }
+    },
+    "snapsvg": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/snapsvg/-/snapsvg-0.5.1.tgz",
+      "integrity": "sha1-DK9Sx5GJopB0b8RGzF6GP2vd3+M=",
+      "requires": {
+        "eve": "~0.5.1"
+      }
+    },
+    "snapsvg-cjs": {
+      "version": "0.0.6",
+      "requires": {
+        "snapsvg": "0.5.1"
+      }
+    },
+    "socket.io": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.1.tgz",
+      "integrity": "sha512-7cBWdsDC7bbyEF6WbBqffjizc/H4YF1wLdZoOzuYfo2uMNSFjJKuQ36t0H40o9B20DO6p+mSytEd92oP4S15bA==",
+      "dev": true,
+      "requires": {
+        "@types/cookie": "^0.4.0",
+        "@types/cors": "^2.8.8",
+        "@types/node": "^14.14.10",
+        "accepts": "~1.3.4",
+        "base64id": "~2.0.0",
+        "debug": "~4.3.1",
+        "engine.io": "~4.1.0",
+        "socket.io-adapter": "~2.1.0",
+        "socket.io-parser": "~4.0.3"
+      }
+    },
+    "socket.io-adapter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz",
+      "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==",
+      "dev": true
+    },
+    "socket.io-parser": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
+      "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
+      "dev": true,
+      "requires": {
+        "@types/component-emitter": "^1.2.10",
+        "component-emitter": "~1.3.0",
+        "debug": "~4.3.1"
+      }
+    },
+    "sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "requires": {
+        "is-plain-obj": "^1.0.0"
+      }
+    },
+    "sort-keys-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
+      "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
+      "dev": true,
+      "requires": {
+        "sort-keys": "^1.0.0"
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+    },
+    "source-map-resolve": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+      "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz",
+      "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==",
+      "dev": true
+    },
+    "split.js": {
+      "version": "1.6.2"
+    },
+    "sprintf-js": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+      "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
+    },
+    "squeak": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz",
+      "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.0.0",
+        "console-stream": "^0.1.1",
+        "lpad-align": "^1.0.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+          "dev": true
+        }
+      }
+    },
+    "sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "requires": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      }
+    },
+    "ssri": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.1.1"
+      }
+    },
+    "stable": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+      "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+      "dev": true
+    },
+    "statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true
+    },
+    "stream-browserify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+      "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.4",
+        "readable-stream": "^3.5.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "stream-combiner2": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+      "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
+      "dev": true,
+      "requires": {
+        "duplexer2": "~0.1.0",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "stream-http": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.1.1.tgz",
+      "integrity": "sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "^3.0.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "xtend": "^4.0.2"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "stream-splicer": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz",
+      "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "streamroller": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
+      "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
+      "dev": true,
+      "requires": {
+        "date-format": "^2.1.0",
+        "debug": "^4.1.1",
+        "fs-extra": "^8.1.0"
+      },
+      "dependencies": {
+        "date-format": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
+          "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
+          "dev": true
+        }
+      }
+    },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true
+    },
+    "string-width": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+      "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+      "dev": true,
+      "requires": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.0"
+      }
+    },
+    "string.fromcodepoint": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz",
+      "integrity": "sha1-jZeDM8C8klOPUPOD5IiPPlYZ1lM=",
+      "dev": true
+    },
+    "string.prototype.codepointat": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
+      "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
+      "dev": true
+    },
+    "string.prototype.matchall": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz",
+      "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "has-symbols": "^1.0.1",
+        "internal-slot": "^1.0.2",
+        "regexp.prototype.flags": "^1.3.0",
+        "side-channel": "^1.0.3"
+      }
+    },
+    "string.prototype.trim": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.3.tgz",
+      "integrity": "sha512-16IL9pIBA5asNOSukPfxX2W68BaBvxyiRK16H3RA/lWW9BDosh+w7f+LhomPHpXJ82QEe7w7/rY/S1CV97raLg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
+    "string.prototype.trimend": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
+      "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
+      }
+    },
+    "string.prototype.trimstart": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
+      "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
+      }
+    },
+    "string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "strip-ansi": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        }
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "^0.2.0"
+      }
+    },
+    "strip-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
+      "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw=="
+    },
+    "strip-dirs": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
+      "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
+      "requires": {
+        "is-natural-number": "^4.0.1"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+      "dev": true
+    },
+    "strip-outer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+      "requires": {
+        "escape-string-regexp": "^1.0.2"
+      }
+    },
+    "style-loader": {
+      "version": "2.0.0",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^2.0.0",
+        "schema-utils": "^3.0.0"
+      }
+    },
+    "stylehacks": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
+      "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-selector-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss": {
+          "version": "7.0.35",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+          "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.2",
+            "source-map": "^0.6.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "postcss-selector-parser": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+          "dev": true,
+          "requires": {
+            "dot-prop": "^5.2.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "subarg": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+      "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.1.0"
+      }
+    },
+    "supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "requires": {
+        "has-flag": "^4.0.0"
+      },
+      "dependencies": {
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+        }
+      }
+    },
+    "svg-pathdata": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-5.0.5.tgz",
+      "integrity": "sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow==",
+      "dev": true
+    },
+    "svg2ttf": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-5.0.0.tgz",
+      "integrity": "sha512-xv4ERtuuaY+RQu7G57nKF7agrAGP+Bqmox72+kIbKek5vyAo02Dus901fR995p0E6adc27+kRhPVynDdShUWWw==",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.6",
+        "cubic2quad": "^1.0.0",
+        "lodash": "^4.17.10",
+        "microbuffer": "^1.0.0",
+        "svgpath": "^2.1.5",
+        "xmldom": "~0.1.22"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        }
+      }
+    },
+    "svgicons2svgfont": {
+      "version": "9.1.1",
+      "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-9.1.1.tgz",
+      "integrity": "sha512-iOj7lqHP/oMrLg7S2Iv89LOJUfmIuePefXcs5ul4IsKwcYvL/T/Buahz+nQQJygyuvEMBBXqnCRmnvJggHeJzA==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.12.2",
+        "geometry-interfaces": "^1.1.4",
+        "glob": "^7.1.2",
+        "neatequal": "^1.0.0",
+        "readable-stream": "^2.3.3",
+        "sax": "^1.2.4",
+        "string.fromcodepoint": "^0.2.1",
+        "string.prototype.codepointat": "^0.2.0",
+        "svg-pathdata": "^5.0.0",
+        "transformation-matrix-js": "^2.7.1"
+      }
+    },
+    "svgo": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
+      "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.1",
+        "coa": "^2.0.2",
+        "css-select": "^2.0.0",
+        "css-select-base-adapter": "^0.1.1",
+        "css-tree": "1.0.0-alpha.37",
+        "csso": "^4.0.2",
+        "js-yaml": "^3.13.1",
+        "mkdirp": "~0.5.1",
+        "object.values": "^1.1.0",
+        "sax": "~1.2.4",
+        "stable": "^0.1.8",
+        "unquote": "~1.1.1",
+        "util.promisify": "~1.0.0"
+      }
+    },
+    "svgpath": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.3.0.tgz",
+      "integrity": "sha512-N/4UDu3Y2ICik0daMmFW1tplw0XPs1nVIEVYkTiQfj9/JQZeEtAKaSYwheCwje1I4pQ5r22fGpoaNIvGgsyJyg==",
+      "dev": true
+    },
+    "syntax-error": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+      "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+      "dev": true,
+      "requires": {
+        "acorn-node": "^1.2.0"
+      }
+    },
+    "table": {
+      "version": "6.0.7",
+      "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz",
+      "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^7.0.2",
+        "lodash": "^4.17.20",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.2.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.0.tgz",
+          "integrity": "sha512-svS9uILze/cXbH0z2myCK2Brqprx/+JJYK5pHicT/GQiBfzzhUVAIT6MwqJg8y4xV/zoGsUeuPuwtoiKSGE15g==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^3.1.1",
+            "json-schema-traverse": "^1.0.0",
+            "require-from-string": "^2.0.2",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "json-schema-traverse": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        }
+      }
+    },
+    "tablesorter": {
+      "version": "2.31.3",
+      "requires": {
+        "jquery": ">=1.2.6"
+      },
+      "dependencies": {
+        "jquery": {
+          "version": "3.5.1",
+          "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
+          "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
+        }
+      }
+    },
+    "tapable": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
+      "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==",
+      "dev": true
+    },
+    "tar": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
+      "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
+      "dev": true,
+      "requires": {
+        "chownr": "^2.0.0",
+        "fs-minipass": "^2.0.0",
+        "minipass": "^3.0.0",
+        "minizlib": "^2.1.1",
+        "mkdirp": "^1.0.3",
+        "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true
+        }
+      }
+    },
+    "tar-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+      "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+      "requires": {
+        "bl": "^1.0.0",
+        "buffer-alloc": "^1.2.0",
+        "end-of-stream": "^1.0.0",
+        "fs-constants": "^1.0.0",
+        "readable-stream": "^2.3.0",
+        "to-buffer": "^1.1.1",
+        "xtend": "^4.0.0"
+      }
+    },
+    "temp-dir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
+      "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=",
+      "dev": true
+    },
+    "tempfile": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz",
+      "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=",
+      "dev": true,
+      "requires": {
+        "temp-dir": "^1.0.0",
+        "uuid": "^3.0.1"
+      }
+    },
+    "tempusdominus-bootstrap-4": {
+      "version": "5.39.0",
+      "requires": {
+        "bootstrap": "^4.5.2",
+        "jquery": "^3.5.1",
+        "moment": "^2.29.0",
+        "moment-timezone": "^0.5.31",
+        "popper.js": "^1.16.1"
+      },
+      "dependencies": {
+        "bootstrap": {
+          "version": "4.6.0",
+          "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
+          "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw=="
+        },
+        "jquery": {
+          "version": "3.5.1",
+          "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
+          "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
+        },
+        "moment": {
+          "version": "2.29.1",
+          "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+          "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
+        },
+        "moment-timezone": {
+          "version": "0.5.33",
+          "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
+          "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
+          "requires": {
+            "moment": ">= 2.9.0"
+          }
+        }
+      }
+    },
+    "tempusdominus-core": {
+      "version": "5.19.0",
+      "requires": {
+        "jquery": "^3.5.0",
+        "moment": "~2.24.0",
+        "moment-timezone": "^0.5.28"
+      },
+      "dependencies": {
+        "jquery": {
+          "version": "3.5.1",
+          "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
+          "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
+        },
+        "moment": {
+          "version": "2.24.0",
+          "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+          "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+        },
+        "moment-timezone": {
+          "version": "0.5.33",
+          "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
+          "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
+          "requires": {
+            "moment": ">= 2.9.0"
+          }
+        }
+      }
+    },
+    "terser": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.0.tgz",
+      "integrity": "sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.20.0",
+        "source-map": "~0.7.2",
+        "source-map-support": "~0.5.19"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.7.3",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+          "dev": true
+        }
+      }
+    },
+    "terser-webpack-plugin": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz",
+      "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==",
+      "dev": true,
+      "requires": {
+        "jest-worker": "^26.6.2",
+        "p-limit": "^3.1.0",
+        "schema-utils": "^3.0.0",
+        "serialize-javascript": "^5.0.1",
+        "source-map": "^0.6.1",
+        "terser": "^5.5.1"
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+    },
+    "timers-browserify": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+      "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
+      "dev": true,
+      "requires": {
+        "process": "~0.11.0"
+      }
+    },
+    "timsort": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
+      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
+      "dev": true
+    },
+    "tippy.js": {
+      "version": "6.2.7",
+      "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.2.7.tgz",
+      "integrity": "sha512-k+kWF9AJz5xLQHBi3K/XlmJiyu+p9gsCyc5qZhxxGaJWIW8SMjw1R+C7saUnP33IM8gUhDA2xX//ejRSwqR0tA==",
+      "requires": {
+        "@popperjs/core": "^2.4.4"
+      }
+    },
+    "tmp": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+      "dev": true,
+      "requires": {
+        "rimraf": "^3.0.0"
+      }
+    },
+    "to-buffer": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+      "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg=="
+    },
+    "to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+    },
+    "to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "^7.0.0"
+      }
+    },
+    "toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true
+    },
+    "totalist": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz",
+      "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==",
+      "dev": true
+    },
+    "tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dev": true,
+      "requires": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      }
+    },
+    "transformation-matrix-js": {
+      "version": "2.7.6",
+      "resolved": "https://registry.npmjs.org/transformation-matrix-js/-/transformation-matrix-js-2.7.6.tgz",
+      "integrity": "sha512-1CxDIZmCQ3vA0GGnkdMQqxUXVm3xXAFmglPYRS1hr37LzSg22TC7QAWOT38OmdUvMEs/rqcnkFoAsqvzdiluDg==",
+      "dev": true
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+      "dev": true
+    },
+    "trim-repeated": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+      "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+      "requires": {
+        "escape-string-regexp": "^1.0.2"
+      }
+    },
+    "trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
+    },
+    "tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
+    "ttf2eot": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz",
+      "integrity": "sha1-jmM3pYWr0WCKDISVirSDzmn2ZUs=",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.6",
+        "microbuffer": "^1.0.0"
+      }
+    },
+    "ttf2woff": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz",
+      "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.6",
+        "microbuffer": "^1.0.0",
+        "pako": "^1.0.0"
+      }
+    },
+    "ttf2woff2": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ttf2woff2/-/ttf2woff2-3.0.0.tgz",
+      "integrity": "sha512-5/Web6B0lF/STNAQ0d5vAlRRquuWsNj8wOmKQ9ql9Bsgbx8MsLnNzaBG9vBcSE4s4Ry1QOr/MyUrDUIVgVPEfw==",
+      "dev": true,
+      "requires": {
+        "bindings": "^1.3.0",
+        "bufferstreams": "^2.0.1",
+        "nan": "^2.10.0",
+        "node-gyp": "^4.0.0"
+      }
+    },
+    "tty-browserify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+      "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+      "dev": true
+    },
+    "type-check": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "^1.2.1"
+      }
+    },
+    "type-fest": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+      "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+      "dev": true
+    },
+    "type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "ua-parser-js": {
+      "version": "0.7.23",
+      "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.23.tgz",
+      "integrity": "sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA==",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "3.12.8",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz",
+      "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==",
+      "dev": true,
+      "optional": true
+    },
+    "umd": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+      "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+      "dev": true
+    },
+    "unbzip2-stream": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+      "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+      "requires": {
+        "buffer": "^5.2.1",
+        "through": "^2.3.8"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+          "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+          "requires": {
+            "base64-js": "^1.3.1",
+            "ieee754": "^1.1.13"
+          }
+        }
+      }
+    },
+    "undeclared-identifiers": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz",
+      "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==",
+      "dev": true,
+      "requires": {
+        "acorn-node": "^1.3.0",
+        "dash-ast": "^1.0.0",
+        "get-assigned-identifiers": "^1.2.0",
+        "simple-concat": "^1.0.0",
+        "xtend": "^4.0.1"
+      }
+    },
+    "unicode-canonical-property-names-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+      "dev": true
+    },
+    "unicode-match-property-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+      "dev": true,
+      "requires": {
+        "unicode-canonical-property-names-ecmascript": "^1.0.4",
+        "unicode-property-aliases-ecmascript": "^1.0.4"
+      }
+    },
+    "unicode-match-property-value-ecmascript": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+      "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+      "dev": true
+    },
+    "unicode-property-aliases-ecmascript": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+      "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+      "dev": true
+    },
+    "uniq": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
+    },
+    "uniqs": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+      "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+      "dev": true
+    },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
+    "universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "unquote": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
+      "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=",
+      "dev": true
+    },
+    "unzip-response": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+      "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c="
+    },
+    "uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "url-join": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+      "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+      "dev": true
+    },
+    "url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "requires": {
+        "prepend-http": "^1.0.1"
+      },
+      "dependencies": {
+        "prepend-http": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+          "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+        }
+      }
+    },
+    "url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
+    },
+    "util": {
+      "version": "0.12.3",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz",
+      "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "is-arguments": "^1.0.4",
+        "is-generator-function": "^1.0.7",
+        "is-typed-array": "^1.1.3",
+        "safe-buffer": "^5.1.2",
+        "which-typed-array": "^1.1.2"
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+    },
+    "util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      },
+      "dependencies": {
+        "es-abstract": {
+          "version": "1.17.7",
+          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
+          "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
+          "dev": true,
+          "requires": {
+            "es-to-primitive": "^1.2.1",
+            "function-bind": "^1.1.1",
+            "has": "^1.0.3",
+            "has-symbols": "^1.0.1",
+            "is-callable": "^1.2.2",
+            "is-regex": "^1.1.1",
+            "object-inspect": "^1.8.0",
+            "object-keys": "^1.1.1",
+            "object.assign": "^4.1.1",
+            "string.prototype.trimend": "^1.0.1",
+            "string.prototype.trimstart": "^1.0.1"
+          }
+        }
+      }
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true
+    },
+    "uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true
+    },
+    "v8-compile-cache": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
+      "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "varstream": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/varstream/-/varstream-0.3.2.tgz",
+      "integrity": "sha1-GKxklHZfP/GjWtmkvgU77BiKXeE=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^1.0.33"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.1",
+            "isarray": "0.0.1",
+            "string_decoder": "~0.10.x"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true
+    },
+    "vendors": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+      "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
+      "dev": true
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "vm-browserify": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+      "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+      "dev": true
+    },
+    "void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+      "dev": true
+    },
+    "watchpack": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz",
+      "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==",
+      "dev": true,
+      "requires": {
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.1.2"
+      }
+    },
+    "webfonts-loader": {
+      "version": "7.1.1",
+      "dev": true,
+      "requires": {
+        "@vusion/webfonts-generator": "^0.6.1",
+        "glob": "^7.1.6",
+        "loader-utils": "^1.4.0"
+      },
+      "dependencies": {
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "1.0.1",
+              "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+              "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+              "dev": true,
+              "requires": {
+                "minimist": "^1.2.0"
+              }
+            }
+          }
+        }
+      }
+    },
+    "webpack": {
+      "version": "5.21.2",
+      "dev": true,
+      "requires": {
+        "@types/eslint-scope": "^3.7.0",
+        "@types/estree": "^0.0.46",
+        "@webassemblyjs/ast": "1.11.0",
+        "@webassemblyjs/wasm-edit": "1.11.0",
+        "@webassemblyjs/wasm-parser": "1.11.0",
+        "acorn": "^8.0.4",
+        "browserslist": "^4.14.5",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^5.7.0",
+        "es-module-lexer": "^0.3.26",
+        "eslint-scope": "^5.1.1",
+        "events": "^3.2.0",
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.2.4",
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^4.2.0",
+        "mime-types": "^2.1.27",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^3.0.0",
+        "tapable": "^2.1.1",
+        "terser-webpack-plugin": "^5.1.1",
+        "watchpack": "^2.0.0",
+        "webpack-sources": "^2.1.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "8.0.5",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz",
+          "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==",
+          "dev": true
+        },
+        "webpack-sources": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz",
+          "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==",
+          "dev": true,
+          "requires": {
+            "source-list-map": "^2.0.1",
+            "source-map": "^0.6.1"
+          }
+        }
+      }
+    },
+    "webpack-bundle-analyzer": {
+      "version": "4.4.0",
+      "dev": true,
+      "requires": {
+        "acorn": "^8.0.4",
+        "acorn-walk": "^8.0.0",
+        "chalk": "^4.1.0",
+        "commander": "^6.2.0",
+        "gzip-size": "^6.0.0",
+        "lodash": "^4.17.20",
+        "opener": "^1.5.2",
+        "sirv": "^1.0.7",
+        "ws": "^7.3.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "8.0.5",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz",
+          "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==",
+          "dev": true
+        },
+        "chalk": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+          "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "commander": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+          "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-cli": {
+      "version": "4.5.0",
+      "dev": true,
+      "requires": {
+        "@discoveryjs/json-ext": "^0.5.0",
+        "@webpack-cli/configtest": "^1.0.1",
+        "@webpack-cli/info": "^1.2.2",
+        "@webpack-cli/serve": "^1.3.0",
+        "colorette": "^1.2.1",
+        "commander": "^7.0.0",
+        "enquirer": "^2.3.6",
+        "execa": "^5.0.0",
+        "fastest-levenshtein": "^1.0.12",
+        "import-local": "^3.0.2",
+        "interpret": "^2.2.0",
+        "rechoir": "^0.7.0",
+        "v8-compile-cache": "^2.2.0",
+        "webpack-merge": "^5.7.3"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-7.0.0.tgz",
+          "integrity": "sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA==",
+          "dev": true
+        },
+        "execa": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz",
+          "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.3",
+            "get-stream": "^6.0.0",
+            "human-signals": "^2.1.0",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.1",
+            "onetime": "^5.1.2",
+            "signal-exit": "^3.0.3",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz",
+          "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==",
+          "dev": true
+        },
+        "human-signals": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+          "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+          "dev": true
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "webpack-merge": {
+          "version": "5.7.3",
+          "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz",
+          "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==",
+          "dev": true,
+          "requires": {
+            "clone-deep": "^4.0.1",
+            "wildcard": "^2.0.0"
+          },
+          "dependencies": {
+            "clone-deep": {
+              "version": "4.0.1",
+              "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+              "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+              "dev": true,
+              "requires": {
+                "is-plain-object": "^2.0.4",
+                "kind-of": "^6.0.2",
+                "shallow-clone": "^3.0.0"
+              }
+            },
+            "wildcard": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+              "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "webpack-merge": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
+      "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-sources": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "^2.0.0",
+        "source-map": "~0.6.1"
+      }
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "which-typed-array": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz",
+      "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==",
+      "dev": true,
+      "requires": {
+        "available-typed-arrays": "^1.0.2",
+        "call-bind": "^1.0.0",
+        "es-abstract": "^1.18.0-next.1",
+        "foreach": "^2.0.5",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.1",
+        "is-typed-array": "^1.1.3"
+      }
+    },
+    "wide-align": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^1.0.2 || 2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        }
+      }
+    },
+    "window-size": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
+      "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
+    },
+    "wkx": {
+      "version": "0.5.0",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "dev": true
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "ws": {
+      "version": "7.4.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz",
+      "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==",
+      "dev": true
+    },
+    "xmldom": {
+      "version": "0.1.31",
+      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
+      "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
+      "dev": true
+    },
+    "xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+    },
+    "y18n": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
+      "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
+      "dev": true
+    },
+    "yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    },
+    "yaml": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
+      "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+      "dev": true
+    },
+    "yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
+      "requires": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      }
+    },
+    "yargs-parser": {
+      "version": "20.2.5",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz",
+      "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==",
+      "dev": true
+    },
+    "yarn-audit-html": {
+      "version": "2.0.0",
+      "dev": true,
+      "requires": {
+        "commander": "^7.0.0",
+        "ejs": "~3.0.2",
+        "marked": "^1.1.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-7.0.0.tgz",
+          "integrity": "sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA==",
+          "dev": true
+        }
+      }
+    },
+    "yauzl": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+      "requires": {
+        "buffer-crc32": "~0.2.3",
+        "fd-slicer": "~1.1.0"
+      }
+    },
+    "yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true
+    }
+  }
+}
diff --git a/web/package.json b/web/package.json
index 4200b1f82..2379e9188 100644
--- a/web/package.json
+++ b/web/package.json
@@ -83,10 +83,16 @@
     "@date-io/date-fns": "1.x",
     "@emotion/sheet": "^1.0.1",
     "@fortawesome/fontawesome-free": "^5.14.0",
+    "@fortawesome/fontawesome-svg-core": "^6.1.0",
+    "@fortawesome/free-regular-svg-icons": "^6.1.0",
+    "@fortawesome/free-solid-svg-icons": "^6.1.0",
+    "@fortawesome/react-fontawesome": "^0.1.18",
     "@material-ui/core": "4.11.0",
     "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "4.0.0-alpha.58",
     "@material-ui/pickers": "^3.2.10",
+    "@mui/icons-material": "^5.4.2",
+    "@mui/material": "^5.4.3",
     "@projectstorm/react-diagrams": "^6.6.1",
     "@simonwep/pickr": "^1.5.1",
     "@szhsin/react-menu": "^2.2.0",
@@ -122,6 +128,7 @@
     "date-fns": "^2.24.0",
     "diff-arrays-of-objects": "^1.1.8",
     "dropzone": "^5.9.3",
+    "html-loader": "^3.1.0",
     "html2canvas": "^1.0.0-rc.7",
     "immutability-helper": "^3.0.0",
     "imports-loader": "^2.0.0",
@@ -155,6 +162,8 @@
     "react-dom": "^17.0.1",
     "react-draggable": "^4.4.4",
     "react-rnd": "^10.3.5",
+    "react-fontawesome": "^1.7.1",
+    "react-router-dom": "^6.2.2",
     "react-select": "^4.2.1",
     "react-table": "^7.6.3",
     "react-timer-hook": "^3.0.5",
diff --git a/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js b/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
index dd9874976..d1ee8b3b3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
@@ -68,25 +68,6 @@ define('pgadmin.node.cast', [
 
       },
 
-      // Define the backform model for cast node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Define the schema for cast
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          editable: false, type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode: ['properties'],
-        },
-        {
-          id: 'description', label: gettext('Comment'),
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        },
-        ],
-      }),
-
       getSchema: function(treeNodeInfo, itemNodeData){
         return new CastSchema({
           getTypeOptions: ()=>getNodeAjaxOptions('get_type', this, treeNodeInfo, itemNodeData),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
index c6d7a7e51..5e830af87 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
@@ -12,9 +12,8 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../static/
 
 define('pgadmin.node.event_trigger', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for event trigger collection
   if (!pgBrowser.Nodes['coll-event_trigger']) {
@@ -80,132 +79,6 @@ define('pgadmin.node.event_trigger', [
           }
         );
       },
-      // Define the model for event trigger node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          oid: undefined,
-          name: undefined,
-          eventowner: undefined,
-          is_sys_obj: undefined,
-          comment: undefined,
-          enabled: 'O',
-          eventfuncoid: undefined,
-          eventfunname: undefined,
-          eventname: 'DDL_COMMAND_START',
-          when: undefined,
-          xmin: undefined,
-          source: undefined,
-          language: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'eventowner': userInfo.name}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the event trigger node
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'eventowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'edit','create'], node: 'role',
-          control: Backform.NodeListByNameControl,
-        },{
-          id: 'is_sys_obj', label: gettext('System event trigger?'),
-          cell:'boolean', type: 'switch',
-          mode: ['properties'],
-        },{
-          id: 'comment', label: gettext('Comment'), type: 'multiline',
-        },{
-          id: 'enabled', label: gettext('Trigger enabled?'),
-          group: gettext('Definition'), mode: ['properties', 'edit','create'],
-          options: [
-            {label: gettext('Enable'), value: 'O'},
-            {label: gettext('Disable'), value: 'D'},
-            {label: gettext('Replica'), value: 'R'},
-            {label: gettext('Always'), value: 'A'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'eventfunname', label: gettext('Trigger function'),
-          type: 'text', control: 'node-ajax-options', group: gettext('Definition'),
-          url:'fopts', cache_node: 'trigger_function',
-        },{
-          id: 'eventname', label: gettext('Event'),
-          group: gettext('Definition'), cell: 'string',
-          options: [
-            {label: gettext('DDL COMMAND START'), value: 'DDL_COMMAND_START'},
-            {label: gettext('DDL COMMAND END'), value: 'DDL_COMMAND_END'},
-            {label: gettext('SQL DROP'), value: 'SQL_DROP'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'when', label: gettext('When TAG in'),  cell: 'string',
-          type: 'text', group: gettext('Definition'),
-          control: Backform.SqlFieldControl,
-          extraClasses:['custom_height_css_class'],
-        },{
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
-          group: gettext('Security'), mode: ['edit', 'create'],
-          min_version: 90200, canAdd: true,
-          canEdit: false, canDelete: true, control: 'unique-col-collection',
-        },
-        ],
-        // event trigger model data validation.
-        validate: function() {
-          var msg = undefined;
-          // Clear any existing error msg.
-          this.errorModel.clear();
-
-          if (_.isUndefined(this.get('name'))
-              || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventowner'))
-              || String(this.get('eventowner')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger owner cannot be empty.');
-            this.errorModel.set('eventowner', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('enabled'))) {
-            msg = gettext('Event trigger enabled status cannot be empty.');
-            this.errorModel.set('enabled', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventfunname'))
-              || String(this.get('eventfunname')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger function cannot be empty.');
-            this.errorModel.set('eventfunname', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventname'))) {
-            msg = gettext('Event trigger event cannot be empty.');
-            this.errorModel.set('eventname', msg);
-            return msg;
-          }
-
-          return null;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
index 6045b0c75..82001e107 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
@@ -13,9 +13,8 @@ import ExtensionsSchema from './extension.ui';
 
 define('pgadmin.node.extension', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   /*
    * Create and Add an Extension Collection into nodes
@@ -96,109 +95,6 @@ define('pgadmin.node.extension', [
        * Define model for the Node and specify the properties
        * of the model in schema.
        */
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [
-          {
-            id: 'name', label: gettext('Name'), first_empty: true,
-            type: 'text', mode: ['properties', 'create', 'edit'],
-            visible: true, url:'avails', readonly: function(m) {
-              return !m.isNew();
-            },
-            transform: function(data, cell) {
-              var res = [],
-                control = cell || this,
-                label = control.model.get('name');
-
-              if (!control.model.isNew()) {
-                res.push({label: label, value: label});
-              }
-              else {
-                if (data && _.isArray(data)) {
-                  _.each(data, function(d) {
-                    if (d.installed_version === null)
-
-                      /*
-                       * d contains json data and sets into
-                       * select's option control
-                       *
-                       * We need to stringify data because formatter will
-                       * convert Array Object as [Object] string
-                       */
-                      res.push({label: d.name, value: JSON.stringify(d)});
-                  });
-                }
-              }
-              return res;
-            },
-
-            /*
-             * extends NodeAjaxOptionsControl to override the properties
-             * getValueFromDOM which takes stringified data from option of
-             * select control and parse it. And `onChange` takes the stringified
-             * data from select's option, thus convert it to json format and set the
-             * data into Model which is used to enable/disable the schema field.
-             */
-            control: Backform.NodeAjaxOptionsControl.extend({
-              getValueFromDOM: function() {
-                var data = this.formatter.toRaw(
-                  _.unescape(this.$el.find('select').val()), this.model);
-                /*
-                 * return null if data is empty to prevent it from
-                 * throwing parsing error. Adds check as name can be empty
-                 */
-                if (data === '') {
-                  return null;
-                }
-                else if (typeof(data) === 'string') {
-                  data=JSON.parse(data);
-                }
-                return data.name;
-              },
-
-              /*
-               * When name is changed, extract value from its select option and
-               * set attributes values into the model
-               */
-              onChange: function() {
-                Backform.NodeAjaxOptionsControl.prototype.onChange.apply(
-                  this, arguments
-                );
-                var selectedValue = this.$el.find('select').val();
-                if (selectedValue.trim() != '') {
-                  var d = this.formatter.toRaw(selectedValue, this.model);
-                  if(typeof(d) === 'string')
-                    d=JSON.parse(d);
-                  this.model.set({
-                    'version' : '',
-                    'relocatable': (
-                      (!_.isNull(d.relocatable[0]) &&
-                        !_.isUndefined(d.relocatable[0])) ? d.relocatable[0]: ''
-                    ),
-                  });
-                } else {
-                  this.model.set({
-                    'version': '', 'relocatable': true, 'schema': '',
-                  });
-                }
-              },
-            }),
-          },
-          {
-            id: 'oid', label: gettext('OID'), cell: 'string',
-            type: 'text', mode: ['properties'],
-          },
-          {
-            id: 'owner', label: gettext('Owner'), control: 'node-list-by-name',
-            mode: ['properties'], node: 'role', cell: 'string',
-            cache_level: 'server',
-          },
-          {
-            id: 'comment', label: gettext('Comment'), cell: 'string',
-            type: 'multiline', readonly: true,
-          },
-        ],
-      }),
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['extension'];
         return new ExtensionsSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
index 8f0ed95ef..4dc85aae0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
@@ -13,9 +13,9 @@ import ForeignServerSchema from './foreign_server.ui';
 
 define('pgadmin.node.foreign_server', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/pgadmin',
-  'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
+  'pgadmin.browser', 'pgadmin.browser.collection',
   'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for foreign server collection
   if (!pgBrowser.Nodes['coll-foreign_server']) {
@@ -82,45 +82,6 @@ define('pgadmin.node.foreign_server', [
           }
         );
       },
-
-      // Defining model for foreign server node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'fsrvowner': userInfo.name}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Defining schema for the foreign server node
-        schema: [
-          {
-            id: 'name', label: gettext('Name'), cell: 'string',
-            type: 'text', disabled: function() {
-              return (
-                this.mode == 'edit' && this.node_info.server.version < 90200
-              );
-            },
-          }, {
-            id: 'oid', label: gettext('OID'), cell: 'string',
-            type: 'text', mode: ['properties'],
-          }, {
-            id: 'fsrvowner', label: gettext('Owner'), type: 'text',
-            control: Backform.NodeListByNameControl, node: 'role',
-            mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
-          }, {
-            id: 'description', label: gettext('Comment'), cell: 'string',
-            type: 'multiline',
-          },
-        ],
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
index 5c5be3c85..b45be8187 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
@@ -12,10 +12,10 @@ import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
 import ForeignDataWrapperSchema from './foreign_data_wrapper.ui';
 
 define('pgadmin.node.foreign_data_wrapper', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/gettext', 'sources/url_for', 'jquery',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for foreign data wrapper collection
   if (!pgBrowser.Nodes['coll-foreign_data_wrapper']) {
@@ -87,44 +87,6 @@ define('pgadmin.node.foreign_data_wrapper', [
           }
         );
       },
-
-      // Defining model for foreign data wrapper node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'fdwowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Defining schema for the foreign data wrapper node
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: function() {
-            // name field will be disabled only if edit mode
-            return (
-              this.mode == 'edit'
-            );
-          },
-        }, {
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        }, {
-          id: 'fdwowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
index aaabe734d..56dc670a1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
@@ -10,13 +10,12 @@
 import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../static/js/node_ajax';
 import LanguageSchema from './language.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
-import _ from 'lodash';
 
 define('pgadmin.node.language', [
   'sources/gettext', 'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for languages collection
   if (!pgBrowser.Nodes['coll-language']) {
@@ -71,37 +70,6 @@ define('pgadmin.node.language', [
         }]);
       },
 
-      // Define the model for language node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'lanowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the language node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },{
-          id: 'lanowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false },
-        },
-        {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        },
-        ],
-      }),
 
       getSchema: function(treeNodeInfo, itemNodeData){
         return new LanguageSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
index b767057cd..697ddf265 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
@@ -12,9 +12,9 @@ import PublicationSchema from './publication.ui';
 
 define('pgadmin.node.publication', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for publications collection
   if (!pgBrowser.Nodes['coll-publication']) {
@@ -23,7 +23,7 @@ define('pgadmin.node.publication', [
         node: 'publication',
         label: gettext('Publications'),
         type: 'coll-publication',
-        columns: ['name', 'pubowner', 'pubtable', 'all_table'],
+        columns: ['name', 'pubowner', 'proptable', 'all_table'],
 
       });
   }
@@ -70,82 +70,7 @@ define('pgadmin.node.publication', [
           icon: 'wcTabIcon icon-publication', data: {action: 'create'},
         }]);
       },
-      // Define the model for publication node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
 
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'pubowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the publication node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-          visible: function() {
-            if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
-              && !_.isUndefined(this.node_info.server.version) &&
-                this.node_info.server.version >= 100000) {
-              return true;
-            }
-            return false;
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },{
-          id: 'pubowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          disabled: function(m){
-            if(m.isNew())
-              return true;
-            return false;
-          },
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
-        },{
-          id: 'all_table', label: gettext('All tables?'), type: 'switch',
-          group: gettext('Definition'), mode: ['edit', 'properties', 'create'], deps: ['name'],
-          readonly: function(m) {return !m.isNew();},
-        },
-        {
-          id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
-          mode: ['properties'],
-        },
-        ],
-
-
-        /* validate function is used to validate the input given by
-         * the user. In case of error, message will be displayed on
-         * the GUI for the respective control.
-         */
-
-        sessChanged: function() {
-          if (this.sessAttrs['pubtable'] == '' && this.origSessAttrs['pubtable'] == '')
-            return false;
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-
-        canCreate: function(itemData, item) {
-
-          var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
-            server = treeData['server'];
-
-          // If server is less than 10 then do not allow 'create' menu
-          if (server && server.version < 100000)
-            return false;
-
-          // by default we want to allow create menu
-          return true;
-        },
-
-      }),
 
       getSchema: function(treeNodeInfo, itemNodeData){
         return new PublicationSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
index 46cfb0e87..55736d4b0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
@@ -147,7 +147,7 @@ export default class PublicationSchema extends BaseUISchema {
       group: gettext('Definition'), mode: ['edit', 'create'],
       deps: ['all_table'], disabled: obj.isAllTable,
     },{
-      id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
+      id: 'proptable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
       mode: ['properties'],
     },{
       type: 'nested-fieldset', mode: ['create','edit', 'properties'],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
index 58eac45a8..668b4eba5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
@@ -1,3 +1,6 @@
 SELECT pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
-AS pubtable  FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
+AS pubtable,
+pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
+AS proptable
+  FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
 AND pgb_table.schemaname NOT LIKE 'pgagent';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
index 25c0f04fc..df8d9b4f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
@@ -45,37 +45,6 @@ define('pgadmin.node.aggregate', [
 
         this.initialized = true;
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Aggregate'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }
-        ],
-      }),
       getSchema: ()=>{
         return new AggregateSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
index 8785d147a..e1152eb22 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
@@ -45,32 +45,6 @@ define('pgadmin.node.catalog_object_column', [
         getSchema: function() {
           return new CatalogObjectColumnSchema();
         },
-        model: pgAdmin.Browser.Node.Model.extend({
-          defaults: {
-            attname: undefined,
-            attowner: undefined,
-            atttypid: undefined,
-            attnum: undefined,
-            cltype: undefined,
-            collspcname: undefined,
-            attacl: undefined,
-            is_sys_obj: undefined,
-            description: undefined,
-          },
-          schema: [{
-            id: 'attname', label: gettext('Column'), cell: 'string',
-            type: 'text', readonly: true,
-          },{
-            id: 'attnum', label: gettext('Position'), cell: 'string',
-            type: 'text', readonly: true,
-          },{
-            id: 'cltype', label: gettext('Data type'), cell: 'string',
-            group: gettext('Definition'), type: 'text', readonly: true,
-          },{
-            id: 'description', label: gettext('Comment'), cell: 'string',
-            type: 'multiline', readonly: true,
-          }],
-        }),
       });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
index 06753a427..dac46721a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
@@ -43,31 +43,6 @@ define('pgadmin.node.catalog_object', [
 
       },
       getSchema: ()=>new CatalogObjectSchema(),
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgAdmin.Browser.Node.Model.extend({
-        defaults: {
-          name: undefined,
-          namespaceowner: undefined,
-          nspacl: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline' ,  readonly: true,
-        },
-        ],
-      }),
 
     });
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
index 586f410bc..4d3dff132 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
@@ -69,42 +69,6 @@ define('pgadmin.node.collation', [
         ]);
 
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema', control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }
-        ],
-      }),
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['collation'];
         return new CollationSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
index 67f23e5ca..4c6594ddb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
@@ -75,43 +75,6 @@ define('pgadmin.node.domain_constraints', [
       getSchema: function() {
         return new DomainConstraintSchema();
       },
-
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        // Domain Constraint Schema
-        schema: [{
-          id: 'name', label: gettext('Name'), type:'text', cell:'string',
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline', cell:
-          'string', mode: ['properties', 'create', 'edit'], min_version: 90500,
-        }],
-        // Client Side Validation
-        validate: function() {
-          var err = {},
-            errmsg;
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('consrc')) || String(this.get('consrc')).replace(/^\s+|\s+$/g, '') == '') {
-            err['consrc'] = gettext('Check cannot be empty.');
-            errmsg = errmsg || err['consrc'];
-
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
index a14fbf395..8b2b361f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
@@ -98,38 +98,6 @@ define('pgadmin.node.domain', [
           }
         );
       },
-
-      // Domain Node Model
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema = args.node_info.schema.label;
-            this.set({'basensp': schema}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'owner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        // Domain Schema
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string', control: Backform.NodeListByNameControl,
-          node: 'role',  type: 'text', mode: ['edit', 'create', 'properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
index 8e6059486..3affdeefb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
@@ -10,15 +10,16 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../stat
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import ForeignTableSchema from './foreign_table.ui';
+import _ from 'lodash';
 
 /* Create and Register Foreign Table Collection and Node. */
 define('pgadmin.node.foreign_table', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.backgrid',
+  'sources/gettext', 'sources/url_for', 'jquery', 'backbone',
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backgrid',
   'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node',
   'pgadmin.browser.collection',
 ], function(
-  gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser, Backform, Backgrid,
+  gettext, url_for, $, Backbone, pgAdmin, pgBrowser, Backgrid,
   schemaChild, schemaChildTreeNode
 ) {
 
@@ -34,465 +35,6 @@ define('pgadmin.node.foreign_table', [
       });
   }
 
-  // Options Model
-  var ColumnOptionsModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'option',
-    defaults: {
-      option: undefined,
-      value: undefined,
-    },
-    schema: [
-      {id: 'option', label: gettext('Option'), type:'text', editable: true, cellHeaderClasses: 'width_percent_30'},
-      {
-        id: 'value', label: gettext('Value'), type: 'text', editable: true, cellHeaderClasses: 'width_percent_50',
-      },
-    ],
-    validate: function() {
-      if (_.isUndefined(this.get('value')) ||
-          _.isNull(this.get('value')) ||
-          String(this.get('value')).replace(/^\s+|\s+$/g, '') == '') {
-        var msg = 'Please enter a value.';
-
-        this.errorModel.set('value', msg);
-
-        return msg;
-      } else {
-        this.errorModel.unset('value');
-      }
-
-      return null;
-    },
-  });
-
-  // Columns Model
-  var ColumnsModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'attnum',
-    defaults: {
-      attname: undefined,
-      datatype: undefined,
-      typlen: undefined,
-      precision: undefined,
-      typdefault: undefined,
-      attnotnull: undefined,
-      collname: undefined,
-      attnum: undefined,
-      inheritedfrom: undefined,
-      inheritedid: undefined,
-      attstattarget: undefined,
-      coloptions: [],
-    },
-    type_options: undefined,
-    schema: [{
-      id: 'attname', label: gettext('Name'), cell: 'string', type: 'text',
-      editable: 'is_editable_column', cellHeaderClasses: 'width_percent_40',
-    },{
-      id: 'datatype', label: gettext('Data type'), cell: 'node-ajax-options',
-      control: 'node-ajax-options', type: 'text', url: 'get_types',
-      editable: 'is_editable_column', cellHeaderClasses: 'width_percent_0',
-      group: gettext('Definition'),
-      transform: function(d, self){
-        self.model.type_options = d;
-        return d;
-      },
-    },
-    {
-      id: 'typlen', label: gettext('Length'),
-      cell: 'string', group: gettext('Definition'),
-      type: 'int', deps: ['datatype'],
-      disabled: function(m) {
-        var val = m.get('typlen');
-        // We will store type from selected from combobox
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) {
-
-          if (!_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('typlen', undefined);
-            }, 10);
-          }
-          return true;
-        }
-
-        var of_type = m.get('datatype'),
-          has_length = false;
-        if(m.type_options) {
-          m.set('is_tlength', false, {silent: true});
-
-          // iterating over all the types
-          _.each(m.type_options, function(o) {
-            // if type from selected from combobox matches in options
-            if ( of_type == o.value ) {
-              // if length is allowed for selected type
-              if(o.length)
-              {
-                // set the values in model
-                has_length = true;
-                m.set('is_tlength', true, {silent: true});
-                m.set('min_val', o.min_val, {silent: true});
-                m.set('max_val', o.max_val, {silent: true});
-              }
-            }
-          });
-
-          if (!has_length && !_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('typlen', undefined);
-            }, 10);
-          }
-
-          return !(m.get('is_tlength'));
-        }
-        if (!has_length && !_.isUndefined(val)) {
-          setTimeout(function() {
-            m.set('typlen', undefined);
-          }, 10);
-        }
-        return true;
-      },
-      cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'precision', label: gettext('Precision'),
-      type: 'int', deps: ['datatype'],
-      cell: 'string', group: gettext('Definition'),
-      disabled: function(m) {
-        var val = m.get('precision');
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) {
-
-          if (!_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('precision', undefined);
-            }, 10);
-          }
-          return true;
-        }
-
-        var of_type = m.get('datatype'),
-          has_precision = false;
-
-        if(m.type_options) {
-          m.set('is_precision', false, {silent: true});
-          // iterating over all the types
-          _.each(m.type_options, function(o) {
-            // if type from selected from combobox matches in options
-            if ( of_type == o.value ) {
-              // if precession is allowed for selected type
-              if(o.precision)
-              {
-                has_precision = true;
-                // set the values in model
-                m.set('is_precision', true, {silent: true});
-                m.set('min_val', o.min_val, {silent: true});
-                m.set('max_val', o.max_val, {silent: true});
-              }
-            }
-          });
-          if (!has_precision && !_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('precision', undefined);
-            }, 10);
-          }
-          return !(m.get('is_precision'));
-        }
-        if (!has_precision && !_.isUndefined(val)) {
-          setTimeout(function() {
-            m.set('precision', undefined);
-          }, 10);
-        }
-        return true;
-      }, cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'typdefault', label: gettext('Default'), type: 'text',
-      cell: 'string', min_version: 90300, group: gettext('Definition'),
-      placeholder: gettext('Enter an expression or a value.'),
-      cellHeaderClasses: 'width_percent_10',
-      editable: function(m) {
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) { return false; }
-        if (this.get('node_info').server.version < 90300){
-          return false;
-        }
-        return true;
-      },
-    },
-    {
-      id: 'attnotnull', label: gettext('Not NULL?'),
-      cell: 'boolean',type: 'switch', editable: 'is_editable_column',
-      cellHeaderClasses: 'width_percent_10', group: gettext('Definition'),
-    },
-    {
-      id: 'attstattarget', label: gettext('Statistics'), min_version: 90200,
-      cell: 'integer', type: 'int', group: gettext('Definition'),
-      editable: function(m) {
-        if (_.isUndefined(m.isNew) || m.isNew()) { return false; }
-        if (this.get('node_info').server.version < 90200){
-          return false;
-        }
-        return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-          || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-      }, cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'collname', label: gettext('Collation'), cell: 'node-ajax-options',
-      control: 'node-ajax-options', type: 'text', url: 'get_collations',
-      min_version: 90300, editable: function(m) {
-        if (!(_.isUndefined(m.isNew)) && !m.isNew()) { return false; }
-        return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-           || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-      },
-      cellHeaderClasses: 'width_percent_20', group: gettext('Definition'),
-    },
-    {
-      id: 'attnum', cell: 'string',type: 'text', visible: false,
-    },
-    {
-      id: 'inheritedfrom', label: gettext('Inherited From'), cell: 'string',
-      type: 'text', visible: false, mode: ['properties', 'edit'],
-      cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'coloptions', label: gettext('Options'), cell: 'string',
-      type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
-      model: ColumnOptionsModel, canAdd: true, canDelete: true, canEdit: false,
-      control: Backform.UniqueColCollectionControl, uniqueCol : ['option'],
-      min_version: 90200,
-    }],
-    validate: function() {
-      var errmsg = null;
-
-      if (_.isUndefined(this.get('attname')) || String(this.get('attname')).replace(/^\s+|\s+$/g, '') == '') {
-        errmsg = gettext('Column Name cannot be empty.');
-        this.errorModel.set('attname', errmsg);
-      } else {
-        this.errorModel.unset('attname');
-      }
-
-      if (_.isUndefined(this.get('datatype')) || String(this.get('datatype'))
-        .replace(/^\s+|\s+$/g, '') == '') {
-        errmsg = gettext('Column Datatype cannot be empty.');
-        this.errorModel.set('datatype', errmsg);
-      } else {
-        this.errorModel.unset('datatype');
-      }
-
-      return errmsg;
-    },
-    is_editable_column: function(m) {
-      return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-       || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
-  /* NodeAjaxOptionsMultipleControl is for multiple selection of Combobox.
-  *  This control is used to select Multiple Parent Tables to be inherited.
-  *  It also populates/vacates Columns on selection/deselection of the option (i.e. table name).
-  *  To populates the column, it calls the server and fetch the columns data
-  *  for the selected table.
-  */
-  var NodeAjaxOptionsMultipleControl = Backform.NodeAjaxOptionsControl.extend({
-    onChange: function() {
-      var model = this.model,
-        attrArr = this.field.get('name').split('.'),
-        name = attrArr.shift(),
-        path = attrArr.join('.'),
-        value = this.getValueFromDOM(),
-        changes = {},
-        columns = model.get('columns'),
-        inherits = model.get(name);
-
-      if (this.model.errorModel instanceof Backbone.Model) {
-        if (_.isEmpty(path)) {
-          this.model.errorModel.unset(name);
-        } else {
-          var nestedError = this.model.errorModel.get(name);
-          if (nestedError) {
-            this.keyPathSetter(nestedError, path, null);
-            this.model.errorModel.set(name, nestedError);
-          }
-        }
-      }
-
-      var self = this;
-
-      if (typeof(inherits)  == 'string'){ inherits = JSON.parse(inherits); }
-
-      // Remove Columns if inherit option is deselected from the combobox
-      if(_.size(value) < _.size(inherits)) {
-        var dif =  _.difference(inherits, value);
-        var rmv_columns = columns.where({inheritedid: parseInt(dif[0])});
-        columns.remove(rmv_columns);
-      }
-      else
-      {
-        _.each(value, function(i) {
-          // Fetch Columns from server
-          var fnd_columns = columns.where({inheritedid: parseInt(i)});
-          if (fnd_columns && fnd_columns.length <= 0) {
-            var inhted_columns = self.fetchColumns(i);
-            columns.add(inhted_columns);
-          }
-        });
-      }
-
-      changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
-      this.stopListening(this.model, 'change:' + name, this.render);
-      model.set(changes);
-      this.listenTo(this.model, 'change:' + name, this.render);
-    },
-    fetchColumns: function(table_id){
-      var self = this,
-        url = 'get_columns',
-        m = self.model.top || self.model;
-
-      var node = this.field.get('schema_node'),
-        node_info = this.field.get('node_info'),
-        full_url = node.generate_url.apply(
-          node, [
-            null, url, this.field.get('node_data'),
-            this.field.get('url_with_id') || false, node_info,
-          ]),
-        cache_level = this.field.get('cache_level') || node.type,
-        cache_node = this.field.get('cache_node');
-
-      cache_node = (cache_node && pgBrowser.Nodes['cache_node']) || node;
-
-      m.trigger('pgadmin:view:fetching', m, self.field);
-      var data = {attrelid: table_id};
-
-      // Fetching Columns data for the selected table.
-      $.ajax({
-        async: false,
-        url: full_url,
-        data: data,
-      })
-        .done(function(res) {
-        /*
-         * We will cache this data for short period of time for avoiding
-         * same calls.
-         */
-          data = cache_node.cache(url, node_info, cache_level, res.data);
-
-        })
-        .fail(function() {
-          m.trigger('pgadmin:view:fetch:error', m, self.field);
-        });
-      m.trigger('pgadmin:view:fetched', m, self.field);
-
-      // To fetch only options from cache, we do not need time from 'at'
-      // attribute but only options.
-      //
-      // It is feasible that the data may not have been fetched.
-      data = (data && data.data) || [];
-      return data;
-
-    },
-  });
-
-
-  // Constraints Model
-  var ConstraintModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'conoid',
-    initialize: function(attrs) {
-      var isNew = (_.size(attrs) === 0);
-      if (!isNew) {
-        this.convalidated_default = this.get('convalidated');
-      }
-      pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-    },
-    defaults: {
-      conoid: undefined,
-      conname: undefined,
-      consrc: undefined,
-      connoinherit: undefined,
-      convalidated: true,
-      conislocal: undefined,
-    },
-    convalidated_default: true,
-    schema: [{
-      id: 'conoid', type: 'text', cell: 'string', visible: false,
-    },{
-      id: 'conname', label: gettext('Name'), type: 'text', cell: 'string',
-      editable: 'is_editable', cellHeaderClasses: 'width_percent_30',
-    },{
-      id: 'consrc', label: gettext('Check'), type: 'multiline',
-      editable: 'is_editable', cell: Backgrid.Extension.TextareaCell,
-      cellHeaderClasses: 'width_percent_30',
-    },{
-      id: 'connoinherit', label: gettext('No inherit?'), type: 'switch',
-      cell: 'boolean', editable: 'is_editable',
-      cellHeaderClasses: 'width_percent_20',
-    },{
-      id: 'convalidated', label: gettext('Validate?'), type: 'switch',
-      cell: 'boolean', cellHeaderClasses: 'width_percent_20',
-      editable: function(m) {
-        if (_.isUndefined(m.isNew)) { return true; }
-        if (!m.isNew()) {
-          if(m.get('convalidated') && m.convalidated_default) {
-            return false;
-          }
-          return true;
-        }
-        return true;
-      },
-    },
-    ],
-    validate: function() {
-      var err = {},
-        errmsg;
-
-      if (_.isUndefined(this.get('conname')) || String(this.get('conname')).replace(/^\s+|\s+$/g, '') == '') {
-        err['conname'] = gettext('Constraint Name cannot be empty.');
-        errmsg = err['conname'];
-      }
-
-      if (_.isUndefined(this.get('consrc')) || String(this.get('consrc'))
-        .replace(/^\s+|\s+$/g, '') == '') {
-        err['consrc'] = gettext('Constraint Check cannot be empty.');
-        errmsg = errmsg || err['consrc'];
-      }
-
-      this.errorModel.clear().set(err);
-
-      return errmsg;
-    },
-    is_editable: function(m) {
-      return _.isUndefined(m.isNew) ? true : m.isNew();
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
-  // Options Model
-  var OptionsModel = pgBrowser.Node.Model.extend({
-    defaults: {
-      option: undefined,
-      value: undefined,
-    },
-    schema: [{
-      id: 'option', label: gettext('Option'), cell: 'string', type: 'text',
-      editable: true, cellHeaderClasses:'width_percent_50',
-    },{
-      id: 'value', label: gettext('Value'), cell: 'string',type: 'text',
-      editable: true, cellHeaderClasses:'width_percent_50',
-    },
-    ],
-    validate: function() {
-      // TODO: Add validation here
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
   if (!pgBrowser.Nodes['foreign_table']) {
     pgBrowser.Nodes['foreign_table'] = schemaChild.SchemaChildNode.extend({
       type: 'foreign_table',
@@ -561,160 +103,6 @@ define('pgadmin.node.foreign_table', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var schema = args.node_info.schema._label,
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            // Set Selected Schema and Current User
-            this.set({
-              'basensp': schema, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          owner: undefined,
-          basensp: undefined,
-          is_sys_obj: undefined,
-          description: undefined,
-          ftsrvname: undefined,
-          strftoptions: undefined,
-          inherits: [],
-          columns: [],
-          constraints: [],
-          ftoptions: [],
-          relacl: [],
-          stracl: [],
-          seclabels: [],
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl,
-          node: 'role',  type: 'text', select2: { allowClear: false },
-        },{
-          id: 'basensp', label: gettext('Schema'), cell: 'node-list-by-name',
-          control: 'node-list-by-name', cache_level: 'database', type: 'text',
-          node: 'schema', mode:['create', 'edit'],
-        },{
-          id: 'is_sys_obj', label: gettext('System foreign table?'),
-          cell:'boolean', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        },{
-          id: 'ftsrvname', label: gettext('Foreign server'), cell: 'string', control: 'node-ajax-options',
-          type: 'text', group: gettext('Definition'), url: 'get_foreign_servers',
-          readonly: function(m) { return !m.isNew(); }, cache_node: 'database',
-        },{
-          id: 'inherits', label: gettext('Inherits'), group: gettext('Definition'),
-          type: 'array', min_version: 90500, control: NodeAjaxOptionsMultipleControl,
-          url: 'get_tables', select2: {multiple: true},
-          'cache_level': 'database',
-          transform: function(d) {
-            if (this.field.get('mode') == 'edit') {
-              var oid = this.model.get('oid');
-              var s = _.findWhere(d, {'id': oid});
-              if (s) {
-                d = _.reject(d, s);
-              }
-            }
-            return d;
-          },
-        },{
-          id: 'columns', label: gettext('Columns'), cell: 'string',
-          type: 'collection', group: gettext('Columns'), mode: ['edit', 'create'],
-          model: ColumnsModel, canAdd: true, canDelete: true, canEdit: true,
-          columns: ['attname', 'datatype', 'inheritedfrom'],
-          canDeleteRow: function(m) {
-            return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-              || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-          },
-          canEditRow: function(m) {
-            return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-              || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-          },
-        },
-        {
-          id: 'constraints', label: gettext('Constraints'), cell: 'string',
-          type: 'collection', group: gettext('Constraints'), mode: ['edit', 'create'],
-          model: ConstraintModel, canAdd: true, canDelete: true, columns: ['conname','consrc', 'connoinherit', 'convalidated'],
-          canEdit: function(o) {
-            if (o instanceof Backbone.Model) {
-              if (o instanceof ConstraintModel) {
-                return o.isNew();
-              }
-            }
-            return true;
-          }, min_version: 90500, canDeleteRow: function(m) {
-            return (m.get('conislocal') == true || _.isUndefined(m.get('conislocal'))) ? true : false;
-          },
-        },{
-          id: 'strftoptions', label: gettext('Options'), cell: 'string',
-          type: 'text', group: gettext('Definition'), mode: ['properties'],
-        },{
-          id: 'ftoptions', label: gettext('Options'), cell: 'string',
-          type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
-          model: OptionsModel, canAdd: true, canDelete: true, canEdit: false,
-          control: 'unique-col-collection', uniqueCol : ['option'],
-        },{
-          id: 'relacl', label: gettext('Privileges'), cell: 'string',
-          type: 'text', group: gettext('Security'),
-          mode: ['properties'], min_version: 90200,
-        }, pgBrowser.SecurityGroupSchema, {
-          id: 'acl', label: gettext('Privileges'), model: pgAdmin
-            .Browser.Node.PrivilegeRoleModel.extend(
-              {privileges: ['a','r','w','x']}), uniqueCol : ['grantee', 'grantor'],
-          editable: false, type: 'collection', group: 'security',
-          mode: ['edit', 'create'],
-          canAdd: true, canDelete: true, control: 'unique-col-collection',
-          min_version: 90200,
-        },{
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, type: 'collection',
-          group: 'security', mode: ['edit', 'create'],
-          min_version: 90100, canAdd: true,
-          canEdit: false, canDelete: true,
-          control: 'unique-col-collection', uniqueCol : ['provider'],
-        },
-        ],
-        validate: function()
-        {
-          var err = {},
-            errmsg = null;
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('basensp')) || String(this.get('basensp'))
-            .replace(/^\s+|\s+$/g, '') == '') {
-            err['basensp'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['basensp'];
-          }
-
-          if (_.isUndefined(this.get('ftsrvname')) || String(this.get('ftsrvname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['ftsrvname'] = gettext('Foreign server cannot be empty.');
-            errmsg = errmsg || err['ftsrvname'];
-          }
-
-          this.errorModel.clear().set(err);
-
-          return errmsg;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
index 0049de5bd..073dd4acc 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
@@ -93,32 +93,6 @@ define('pgadmin.node.fts_configuration', [
           }
         );
       },
-
-      // Defining model for FTS Configuration node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        initialize: function(attrs, opts) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-          if (isNew) {
-            var user = pgBrowser.serverInfo[opts.node_info.server._id].user;
-            this.set({
-              'owner': user.name,
-              'schema': opts.node_info.schema._id,
-            }, {silent: true});
-          }
-        },
-        // Defining schema for FTS Configuration
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
index 5d5bd3a8f..0ea741034 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
@@ -88,31 +88,6 @@ define('pgadmin.node.fts_dictionary', [
           }
         );
       },
-
-      // Defining backform model for FTS Dictionary node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-          if (isNew) {
-            var user = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'owner': user.name,
-              'schema': args.node_info.schema._id,
-            }, {silent: true});
-          }
-        },
-        // Defining schema for fts dictionary
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
index 27a4ce87f..ad5579d0d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
@@ -70,108 +70,6 @@ define('pgadmin.node.fts_parser', [
 
       },
 
-      // Defining backform model for fts parser node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,          // Fts parser name
-          is_sys_obj: undefined,  // Is system object
-          description: undefined,   // Comment on parser
-        },
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(
-            this, arguments
-          );
-          if (isNew) {
-            this.set('schema', args.node_info.schema._id);
-          }
-        },
-        // Defining schema for fts parser
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode:['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-
-        /*
-         * Triggers control specific error messages for parser name,
-         * start, token, end, lextype functions and schema, if any one of them is not specified
-         * while creating new fts parser
-         */
-        validate: function() {
-          var name = this.get('name'),
-            start = this.get('prsstart'),
-            token = this.get('prstoken'),
-            end = this.get('prsend'),
-            lextype = this.get('prslextype'),
-            schema = this.get('schema'),
-            msg;
-
-          // Validate fts parser name
-          if (_.isUndefined(name) ||
-                _.isNull(name) ||
-                String(name).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name must be specified.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          // Validate start function control
-          else if (_.isUndefined(start) ||
-                    _.isNull(start) ||
-                    String(start).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Start function must be selected.');
-            this.errorModel.set('prsstart', msg);
-            return msg;
-          }
-
-          // Validate gettoken function control
-          else if (_.isUndefined(token) ||
-                    _.isNull(token) ||
-                    String(token).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Get next token function must be selected.');
-            this.errorModel.set('prstoken', msg);
-            return msg;
-          }
-
-          // Validate end function control
-          else if (_.isUndefined(end) ||
-                    _.isNull(end) ||
-                    String(end).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('End function must be selected.');
-            this.errorModel.set('prsend', msg);
-            return msg;
-          }
-
-          // Validate lextype function control
-          else if (_.isUndefined(lextype) ||
-                    _.isNull(lextype) ||
-                    String(lextype).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Lextype function must be selected.');
-            this.errorModel.set('prslextype', msg);
-            return msg;
-          }
-
-          // Validate schema for fts parser
-          else if (_.isUndefined(schema) ||
-                    _.isNull(schema) ||
-                    String(schema).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Schema must be selected.');
-            this.errorModel.set('schema', msg);
-            return msg;
-          }
-          else this.errorModel.clear();
-
-          this.trigger('on-status-clear');
-          return null;
-        },
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['fts_parser'];
         return new FTSParserSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
index 791adb2f9..5320246f3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
@@ -70,65 +70,6 @@ define('pgadmin.node.fts_template', [
 
       },
 
-      // Defining backform model for fts template node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-          if (isNew) {
-            this.set('schema', args.node_info.schema._id);
-          }
-        },
-        // Defining schema for fts template
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode:['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-
-        /*
-         * Triggers control specific error messages for template name,
-         * lexize function and schema, if any one of them is not specified
-         * while creating new fts template
-         */
-        validate: function() {
-          var name = this.get('name'),
-            lexize = this.get('tmpllexize'),
-            schema = this.get('schema'),
-            msg;
-
-          // Validate fts template name
-          if (_.isUndefined(name) || _.isNull(name) || String(name).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name must be specified.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          // Validate lexize function control
-          else if (_.isUndefined(lexize) || _.isNull(lexize) || String(lexize).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Lexize function must be selected.');
-            this.errorModel.set('tmpllexize', msg);
-            return msg;
-          }
-
-          // Validate schema for fts template
-          else if (_.isUndefined(schema) || _.isNull(schema) || String(schema).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Schema must be selected.');
-            this.errorModel.set('schema', msg);
-            return msg;
-          }
-          else this.errorModel.clear();
-
-          this.trigger('on-status-clear');
-          return null;
-        },
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['fts_template'];
         return new FTSTemplateSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
index 41171c62a..b9107d98f 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
 import FunctionSchema from './function.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
-import _ from 'lodash';
 
 /* Create and Register Function Collection and Node. */
 define('pgadmin.node.function', [
@@ -109,44 +108,7 @@ define('pgadmin.node.function', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema_id = args.node_info.schema._id;
-            this.set({'pronamespace': schema_id}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'funcowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'isDisabled',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'funcowner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl, node: 'role',  type:
-          'text', disabled: 'isDisabled',
-        },{
-          id: 'pronamespace', label: gettext('Schema'), cell: 'string',
-          control: 'node-list-by-id', type: 'text', cache_level: 'database',
-          node: 'schema', disabled: 'isDisabled', mode: ['create', 'edit'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled',
-        }],
-      }),
     });
-
   }
-
   return pgBrowser.Nodes['function'];
 });
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
index 1b6b61863..7cbcdc907 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
 import FunctionSchema from './function.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
-import _ from 'lodash';
 
 /* Create and Register Procedure Collection and Node. */
 define('pgadmin.node.procedure', [
@@ -126,126 +125,6 @@ define('pgadmin.node.procedure', [
         );
       },
 
-      model: Function.model.extend({
-        defaults: _.extend({},
-          Function.model.prototype.defaults,
-          {
-            lanname: 'edbspl',
-          }
-        ),
-        canVarAdd: function() {
-          var server = this.node_info.server;
-          return server.version >= 90500;
-        },
-        isVisible: function() {
-          if (this.name == 'sysfunc') { return false; }
-          else if (this.name == 'sysproc') { return true; }
-          return false;
-        },
-        isDisabled: function(m) {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          switch(this.name){
-          case 'provolatile':
-          case 'proisstrict':
-          case 'procost':
-          case 'proleakproof':
-            if(this.node_info.server.version < 90500 ||
-              this.node_info.server.server_type != 'ppas' ||
-              m.get('lanname') != 'edbspl') {
-
-              setTimeout(function() {
-                m.set('provolatile', null);
-                m.set('proisstrict', false);
-                m.set('procost', null);
-                m.set('proleakproof', false);
-              }, 10);
-              return true;
-            }
-            else{
-              return false;
-            }
-          case 'variables':
-          case 'prosecdef':
-            return this.node_info.server.version < 90500;
-          case 'prorows':
-            var server = this.node_info.server;
-            return !(server.version >= 90500 && m.get('proretset') == true);
-          case 'proparallel':
-            if (this.node_info.server.version < 90600 ||
-              this.node_info.server.server_type != 'ppas' ||
-              m.get('lanname') != 'edbspl') {
-              setTimeout(function() {
-                m.set('proparallel', null);
-              }, 10);
-              return true;
-            }
-            else{
-              return false;
-            }
-          case 'lanname':
-            return this.node_info.server.version < 110000;
-          default:
-            return false;
-          }
-        },
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          return null;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
index ec0b9f2c5..1eed8e8bf 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
@@ -107,151 +107,6 @@ define('pgadmin.node.trigger_function', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema_id = args.node_info.schema._id;
-            this.set({'pronamespace': schema_id}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'funcowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          funcowner: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'isDisabled', readonly: 'isReadonly',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'funcowner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl, node: 'role',  type:
-          'text', disabled: 'isDisabled', readonly: 'isReadonly',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled', readonly: 'isReadonly',
-        }],
-        validate: function(keys)
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          // Nothing to validate
-          if(keys && keys.length == 0) {
-            this.errorModel.clear();
-            return null;
-          }
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') {
-            err['funcowner'] = gettext('Owner cannot be empty.');
-            errmsg = errmsg || err['funcowner'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') {
-            err['prorettypename'] = gettext('Return type cannot be empty.');
-            errmsg = errmsg || err['prorettypename'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-        isVisible: function() {
-          if (this.name == 'sysproc') { return false; }
-          return true;
-        },
-        isReadonly: function(m) {
-          switch(this.name){
-          case 'proargs':
-          case 'proargtypenames':
-          case 'prorettypename':
-          case 'proretset':
-          case 'proiswindow':
-            return !m.isNew();
-          default:
-            return false;
-          }
-        },
-        isDisabled: function(m) {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          if (this.name === 'prorows'){
-            if(m.get('proretset') == true) {
-              return false;
-            }
-            return true;
-          } else {
-            return false;
-          }
-        },
-        canVarAdd: function() {
-          return !(this.node_info &&  'catalog' in this.node_info);
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
index 98fff6bab..3a2bb65a8 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
@@ -45,37 +45,6 @@ define('pgadmin.node.operator', [
 
         this.initialized = true;
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Operator'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }
-        ],
-      }),
       getSchema: ()=>{
         return new OperatorSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
index a3c340407..d9ebb9d3d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
@@ -48,16 +48,6 @@ define('pgadmin.node.edbvar', [
       },
       canDrop: false,
       canDropCascade: false,
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        }]
-      }),
       getSchema: () => {
         return new EDBVarSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
index a2ce63fc3..003f379bd 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
@@ -92,41 +92,6 @@ define('pgadmin.node.package', [
         // by default we want to allow create menu
         return true;
       },
-      // Define the model for package node.
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({
-              'owner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        // Define the schema for package node.
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: function(m) {
-            return !m.isNew();
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: true, editable: false, visible: function(m) {
-            return !m.isNew();
-          },
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }]
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         var nodeObj = pgBrowser.Nodes['package'];
         return new PackageSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
index 6c358fd58..0e336682a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
@@ -106,41 +106,6 @@ define('pgadmin.node.sequence', [
           }
         );
       },
-
-      // Define the model for sequence node.
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'seqowner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for sequence node.
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'seqowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
-          control: Backform.NodeListByNameControl,
-        },{
-          id: 'comment', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
index c41cbd5d2..42d182c48 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
@@ -42,25 +42,6 @@ define('pgadmin.node.catalog', [
         this.initialized = true;
 
       },
-      model: pgBrowser.Node.Model.extend({
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'namespaceowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        }]
-      }),
       getSchema: function(treeNodeInfo) {
         return new CatalogSchema(
           {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
index ee384f629..4822c204d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
@@ -361,36 +361,6 @@ define('pgadmin.node.schema', [
       can_create_schema: function(node) {
         return pgBrowser.Nodes['database'].is_conn_allow.call(this, node);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'namespaceowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'namespaceowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', control: 'node-list-by-name', node: 'role',
-          select2: { allowClear: false },
-        },{
-          id: 'is_sys_obj', label: gettext('System schema?'),
-          cell: 'switch', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline'
-        }]
-      }),
       getSchema: function(treeNodeInfo, itemNodeData) {
         var schemaObj = pgBrowser.Nodes['schema'];
         return new PGSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
index 8181fdc94..104324cb3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
@@ -100,54 +100,6 @@ define('pgadmin.node.synonym', [
           }
         );
       },
-
-      model: pgAdmin.Browser.Node.Model.extend({
-        isNew: function() {
-          return !this.fetchFromServer;
-        },
-        idAttribute: 'oid',
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-            this.set({
-              'owner': userInfo.name,
-              'synobjschema': schemaInfo._label,
-              'schema': schemaInfo._label,
-              'targettype': 'r',
-            }, {silent: true});
-          } else {
-            this.fetchFromServer = true;
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema', readonly: function(m) { return !m.isNew(); },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: true , control: 'node-list-by-name',
-          node: 'role', visible: false,
-        }],
-
-        // We will disable everything if we are under catalog node
-        inSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-      }),
       canCreate: function(itemData, item, data) {
         //If check is false then , we will allow create menu
         if (data && data.check == false)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
index 5e12f159a..4df6c7ae7 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
@@ -98,36 +98,6 @@ define('pgadmin.node.column', [
       getSchema: function(treeNodeInfo, itemNodeData) {
         return getNodeColumnSchema(treeNodeInfo, itemNodeData, pgBrowser);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'attnum',
-
-        defaults: {
-          name: undefined,
-          attnum: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchemaWithColumnCheck',
-          cellHeaderClasses:'width_percent_30',
-          editable: 'editable_check_for_table',
-        },{
-          id: 'attnum', label: gettext('Position'), cell: 'string',
-          type: 'text', disabled: 'notInSchema', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'notInSchema',
-        }],
-        // We will check if we are under schema node & in 'create' mode
-        notInSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-      }),
       // Below function will enable right click menu for creating column
       canCreate: function(itemData, item, data) {
         // If check is false then , we will allow create menu
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
index 433828373..06b41026a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
@@ -189,16 +189,6 @@ define('pgadmin.node.compound_trigger', [
         );
       },
 
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }],
-      }),
       canCreate: function(itemData, item, data) {
         //If check is false then , we will allow create menu
         if (data && data.check == false)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
index d135deae5..df5f0e4cb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
@@ -43,24 +43,6 @@ define('pgadmin.node.constraints', [
 
         pgBrowser.add_menus([]);
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          comment: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('Oid'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
index 3fb8a6c17..cb1749c08 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
@@ -92,29 +92,6 @@ define('pgadmin.node.index', [
       },
       canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          nspname: undefined,
-          tabname: undefined,
-          spcname: undefined,
-          amname: 'btree',
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'int', readonly: true, mode: ['properties'],
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }],
-      }),
       // Below function will enable right click menu for creating column
       canCreate: function(itemData, item, data) {
         // If check is false then , we will allow create menu
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
index 7b8b144b9..b360c6b8d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
@@ -305,49 +305,6 @@ function(
       getSchema: function(treeNodeInfo, itemNodeData) {
         return getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowser);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          description: undefined,
-          is_partitioned: false,
-          partition_value: undefined,
-        },
-        // Default values!
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[
-                args.node_info.server._id
-              ].user,
-              schemaInfo = args.node_info.schema;
-
-            this.set({
-              'relowner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), type: 'text', mode: ['properties'],
-        },{
-          id: 'schema', label: gettext('Schema'), type: 'text', node: 'schema',
-          mode: ['create', 'edit', 'properties'],
-        },{
-          id: 'is_partitioned', label:gettext('Partitioned table?'), cell: 'switch',
-          type: 'switch', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'partition_value', label:gettext('Partition Scheme'),
-          type: 'text', visible: false,
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }],
-      }),
       canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       // Check to whether table has disable trigger(s)
       canCreate_with_trigger_enable: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
index acc285e99..d1908a6eb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
@@ -88,64 +88,6 @@ define('pgadmin.node.row_security_policy', [
           }
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
-          mode: ['properties']
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode: ['properties'],
-        }],
-        validate: function(keys) {
-          var msg;
-          this.errorModel.clear();
-          // If nothing to validate
-          if (keys && keys.length == 0) {
-            return null;
-          }
-
-          if(_.isUndefined(this.get('name'))
-            || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-          if (!this.isNew() && !_.isNull(this.get('using_orig')) && this.get('using_orig') != '' && String(this.get('using')).replace(/^\s+|\s+$/g, '') == ''){
-            msg = gettext('"USING" can not be empty once the value is set');
-            this.errorModel.set('using', msg);
-            return msg;
-          }
-          if (!this.isNew() && !_.isNull(this.get('withcheck_orig')) && this.get('withcheck_orig') != '' && String(this.get('withcheck')).replace(/^\s+|\s+$/g, '') == ''){
-            msg = gettext('"Withcheck" can not be empty once the value is set');
-            this.errorModel.set('withcheck', msg);
-            return msg;
-          }
-          return null;
-        },
-        disableWithCheck: function(m){
-          var event = m.get('event');
-          if ((event == 'SELECT') || (event == 'DELETE')){
-            m.set('withcheck', '');
-            return true;
-          }
-          return false;
-        },
-
-        disableUsing: function(m){
-          var event = m.get('event');
-
-          if (event == 'INSERT'){
-            return true;
-          }
-          return false;
-        },
-
-      }),
       canCreate: function(itemData, item) {
 
         var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
index cde25009b..73ebd4183 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
@@ -207,54 +207,6 @@ define('pgadmin.node.rule', [
           }
         );
       },
-      /**
-        Define model for the rule node and specify the node
-        properties of the model in schema.
-       */
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'),
-          type: 'text', disabled: function(m) {
-            // disable name field it it is system rule
-            if (m && m.get('name') == '_RETURN') {
-              return true;
-            }
-            if (m.isNew && m.isNew() || m.node_info && m.node_info.server.version >= 90400) {
-              return false;
-            }
-            return true;
-          },
-        },
-        {
-          id: 'oid', label: gettext('OID'),
-          type: 'text', mode: ['properties'],
-        },
-        {
-          id: 'comment', label: gettext('Comment'), cell: 'string', type: 'multiline',
-        },
-        ],
-        validate: function() {
-
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name');
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') === '')
-          {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }
-          else
-          {
-            this.errorModel.unset('name');
-          }
-          return null;
-        },
-      }),
 
       // Show or hide create rule menu option on parent node
       canCreate: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
index 1e4ecba89..c60ecbc5c 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
@@ -187,468 +187,6 @@ define('pgadmin.node.trigger', [
           },
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          is_row_trigger: true,
-          fires: 'BEFORE',
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'int', mode: ['properties'],
-        },{
-          id: 'is_enable_trigger', label: gettext('Trigger enabled?'),
-          mode: ['edit', 'properties'], group: gettext('Definition'),
-          disabled: function() {
-            if(this.node_info && ('catalog' in this.node_info || 'view' in this.node_info)) {
-              return true;
-            }
-            return false;
-          },
-          options: [
-            {label: gettext('Enable'), value: 'O'},
-            {label: gettext('Enable Replica'), value: 'R'},
-            {label: gettext('Enable Always'), value: 'A'},
-            {label: gettext('Disable'), value: 'D'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'is_row_trigger', label: gettext('Row trigger?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['is_constraint_trigger'],
-          disabled: function(m) {
-            // Disabled if table is a partitioned table.
-            if (!m.isNew())
-              return true;
-
-            if (_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
-              _.has(m.node_info.table, 'is_partitioned') &&
-               m.node_info.table.is_partitioned && m.node_info.server.version < 110000
-            )
-            {
-              setTimeout(function(){
-                m.set('is_row_trigger', false);
-              },10);
-
-              return true;
-            }
-
-            // If constraint trigger is set to True then row trigger will
-            // automatically set to True and becomes disable
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                // change it's model value
-                setTimeout(function() { m.set('is_row_trigger', true); }, 10);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Check if it is row trigger then enabled it.
-              var is_row_trigger = m.get('is_row_trigger');
-              if (!_.isUndefined(is_row_trigger) && m.node_info['server']['server_type'] == 'ppas') {
-                return false;
-              }
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'is_constraint_trigger', label: gettext('Constraint trigger?'),
-          type: 'switch',
-          mode: ['create','edit', 'properties'],
-          group: gettext('Definition'),
-          deps: ['tfunction'],
-          disabled: function(m) {
-            // Disabled if table is a partitioned table.
-            var tfunction = m.get('tfunction');
-            if ((_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
-              _.has(m.node_info.table, 'is_partitioned') &&
-                m.node_info.table.is_partitioned) ||
-                _.indexOf(Object.keys(m.node_info), 'view') != -1 ||
-                (m.node_info.server.server_type === 'ppas' &&
-                !_.isUndefined(tfunction) &&
-                 tfunction === 'Inline EDB-SPL')) {
-              setTimeout(function(){
-                m.set('is_constraint_trigger', false);
-              },10);
-
-              return true;
-            }
-
-            return m.inSchemaWithModelCheck.apply(this, [m]);
-          },
-        },{
-          id: 'tgdeferrable', label: gettext('Deferrable?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['is_constraint_trigger'],
-          disabled: function(m) {
-            // If constraint trigger is set to True then only enable it
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                return false;
-              } else {
-                // If value is already set then reset it to false
-                if(m.get('tgdeferrable')) {
-                  setTimeout(function() { m.set('tgdeferrable', false); }, 10);
-                }
-                return true;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'tginitdeferred', label: gettext('Deferred?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['tgdeferrable', 'is_constraint_trigger'],
-          disabled: function(m) {
-            // If Deferrable is set to True then only enable it
-            var tgdeferrable = m.get('tgdeferrable');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(tgdeferrable) &&
-                tgdeferrable) {
-                return false;
-              } else {
-                // If value is already set then reset it to false
-                if(m.get('tginitdeferred')) {
-                  setTimeout(function() { m.set('tginitdeferred', false); }, 10);
-                }
-                // If constraint trigger is set then do not disable
-                return m.get('is_constraint_trigger') ? false : true;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'tfunction', label: gettext('Trigger function'),
-          type: 'text', disabled: 'inSchemaWithModelCheck',
-          mode: ['create','edit', 'properties'], group: gettext('Definition'),
-          control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema',
-          cache_node: 'trigger_function',
-        },{
-          id: 'tgargs', label: gettext('Arguments'), cell: 'string',
-          group: gettext('Definition'),
-          type: 'text',mode: ['create','edit', 'properties'], deps: ['tfunction'],
-          disabled: function(m) {
-            // We will disable it when EDB PPAS and trigger function is
-            // set to Inline EDB-SPL
-            var tfunction = m.get('tfunction'),
-              server_type = m.node_info['server']['server_type'];
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(server_type === 'ppas' &&
-                !_.isUndefined(tfunction) &&
-                  tfunction === 'Inline EDB-SPL') {
-                // Disable and clear its value
-                m.set('tgargs', undefined);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'fires', label: gettext('Fires'), deps: ['is_constraint_trigger'],
-          mode: ['create','edit', 'properties'], group: gettext('Events'),
-          options: function(control) {
-            var table_options = [
-                {label: 'BEFORE', value: 'BEFORE'},
-                {label: 'AFTER', value: 'AFTER'}],
-              view_options = [
-                {label: 'BEFORE', value: 'BEFORE'},
-                {label: 'AFTER', value: 'AFTER'},
-                {label: 'INSTEAD OF', value: 'INSTEAD OF'}];
-            // If we are under table then show table specific options
-            if(_.indexOf(Object.keys(control.model.node_info), 'table') != -1) {
-              return table_options;
-            } else {
-              return view_options;
-            }
-          },
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-          disabled: function(m) {
-            if (!m.isNew())
-              return true;
-            // If contraint trigger is set to True then only enable it
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                setTimeout(function() { m.set('fires', 'AFTER'); }, 10);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Check if it is row trigger then enabled it.
-              var fires_ = m.get('fires');
-              if (!_.isUndefined(fires_) && m.node_info['server']['server_type'] == 'ppas') {
-                return false;
-              }
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          type: 'nested', control: 'fieldset', mode: ['create','edit', 'properties'],
-          label: gettext('Events'), group: gettext('Events'), contentClass: 'row',
-          schema:[{
-            id: 'evnt_insert', label: gettext('INSERT'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_insert = m.get('evnt_insert');
-              if (!_.isUndefined(evn_insert) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_update', label: gettext('UPDATE'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_update = m.get('evnt_update');
-              if (!_.isUndefined(evn_update) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_delete', label: gettext('DELETE'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_delete = m.get('evnt_delete');
-              if (!_.isUndefined(evn_delete) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_truncate', label: gettext('TRUNCATE'),
-            type: 'switch', group: gettext('Events'),deps: ['is_row_trigger', 'is_constraint_trigger'],
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var is_constraint_trigger = m.get('is_constraint_trigger'),
-                is_row_trigger = m.get('is_row_trigger'),
-                server_type = m.node_info['server']['server_type'];
-              if (is_row_trigger == true){
-                setTimeout(function(){
-                  m.set('evnt_truncate', false);
-                },10);
-                return true;
-              }
-
-              if (server_type === 'ppas' &&
-                  !_.isUndefined(is_constraint_trigger) &&
-                    !_.isUndefined(is_row_trigger) &&
-                    is_constraint_trigger === false && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          }],
-        },{
-          id: 'whenclause', label: gettext('When'),
-          type: 'text', disabled: 'inSchemaWithModelCheck',
-          mode: ['create', 'edit', 'properties'],
-          control: 'sql-field', visible: true, group: gettext('Events'),
-        },{
-          id: 'columns', label: gettext('Columns'), url: 'nodes',
-          control: 'node-list-by-name', cache_node: 'column', type: 'array',
-          select2: {'multiple': true},
-          deps: ['evnt_update'], node: 'column', group: gettext('Events'),
-          disabled: function(m) {
-            if(this.node_info &&  'catalog' in this.node_info) {
-              return true;
-            }
-            //Disable in edit mode
-            if (!m.isNew()) {
-              return true;
-            }
-            // Enable column only if update event is set true
-            var isUpdate = m.get('evnt_update');
-            if(!_.isUndefined(isUpdate) && isUpdate) {
-              return false;
-            }
-            return true;
-          },
-        },{
-          id: 'tgoldtable', label: gettext('Old table'),
-          type: 'text', group: gettext('Transition'),
-          cell: 'string', mode: ['create', 'edit', 'properties'],
-          deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
-          disabled: 'disableTransition',
-        },{
-          id: 'tgnewtable', label: gettext('New table'),
-          type: 'text', group: gettext('Transition'),
-          cell: 'string', mode: ['create', 'edit', 'properties'],
-          deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
-          disabled: 'disableTransition',
-        },{
-          id: 'prosrc', label: gettext('Code'), group: gettext('Code'),
-          type: 'text', mode: ['create', 'edit'], deps: ['tfunction'],
-          tabPanelCodeClass: 'sql-code-control',
-          control: Backform.SqlCodeControl,
-          visible: true,
-          disabled: function(m) {
-            // We will enable it only when EDB PPAS and trigger function is
-            // set to Inline EDB-SPL
-            var tfunction = m.get('tfunction'),
-              server_type = m.node_info['server']['server_type'];
-
-            return (server_type !== 'ppas' ||
-            _.isUndefined(tfunction) ||
-              tfunction !== 'Inline EDB-SPL');
-          },
-        },{
-          id: 'is_sys_trigger', label: gettext('System trigger?'), cell: 'string',
-          type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }],
-        validate: function(keys) {
-          var msg;
-          this.errorModel.clear();
-
-          // If nothing to validate
-          if (keys && keys.length == 0) {
-            return null;
-          }
-
-          if(_.isUndefined(this.get('name'))
-            || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-          if(_.isUndefined(this.get('tfunction'))
-            || String(this.get('tfunction')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Trigger function cannot be empty.');
-            this.errorModel.set('tfunction', msg);
-            return msg;
-          }
-
-          if(!this.get('evnt_truncate') && !this.get('evnt_delete') &&
-            !this.get('evnt_update') && !this.get('evnt_insert')) {
-            msg = gettext('Specify at least one event.');
-            this.errorModel.set('evnt_truncate', ' ');
-            this.errorModel.set('evnt_delete', ' ');
-            this.errorModel.set('evnt_update', ' ');
-            this.errorModel.set('evnt_insert', msg);
-            return msg;
-          }
-
-          if(!_.isUndefined(this.get('tfunction')) &&
-            this.get('tfunction') === 'Inline EDB-SPL' &&
-              (_.isUndefined(this.get('prosrc'))
-                || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == ''))
-          {
-            msg = gettext('Trigger code cannot be empty.');
-            this.errorModel.set('prosrc', msg);
-            return msg;
-          }
-          return null;
-        },
-        // We will check if we are under schema node & in 'create' mode
-        inSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          return false;
-        },
-        // We will check if we are under schema node & in 'create' mode
-        inSchemaWithModelCheck: function(m) {
-          if(this.node_info &&  'schema' in this.node_info) {
-            // We will disable control if it's in 'edit' mode
-            return !m.isNew();
-          }
-          return true;
-        },
-        // Checks weather to enable/disable control
-        inSchemaWithColumnCheck: function(m) {
-          if(this.node_info &&  'schema' in this.node_info) {
-            // We will disable control if it's system columns
-            // ie: it's position is less then 1
-            if (m.isNew()) {
-              return false;
-            } else {
-              // if we are in edit mode
-              return (_.isUndefined(m.get('attnum')) || m.get('attnum') < 1 );
-            }
-          }
-          return true;
-        },
-        // Disable/Enable Transition tables
-        disableTransition: function(m) {
-          if (!m.isNew())
-            return true;
-          var flag = false,
-            evnt = null,
-            name = this.name,
-            evnt_count = 0;
-
-          // Disable transition tables for view trigger and PG version < 100000
-          if(_.indexOf(Object.keys(m.node_info), 'table') == -1 ||
-            m.node_info.server.version < 100000) return true;
-
-          if (name == 'tgoldtable') evnt = 'evnt_delete';
-          else if (name == 'tgnewtable') evnt = 'evnt_insert';
-
-          if(m.get('evnt_insert')) evnt_count++;
-          if(m.get('evnt_update')) evnt_count++;
-          if(m.get('evnt_delete')) evnt_count++;
-
-
-          // Disable transition tables if
-          //  - It is a constraint trigger
-          //  - Fires other than AFTER
-          //  - More than one events enabled
-          //  - Update event with the column list
-
-          // Disable Old transition table if both UPDATE and DELETE events are disabled
-          // Disable New transition table if both UPDATE and INSERT events are disabled
-          if(!m.get('is_constraint_trigger') && m.get('fires') == 'AFTER' &&
-            (m.get('evnt_update') || m.get(evnt)) && evnt_count == 1) {
-            flag = (m.get('evnt_update') && (_.size(m.get('columns')) >= 1 && m.get('columns')[0] != ''));
-          }
-
-          flag && setTimeout(function() {
-            if(m.get(name)) {
-              m.set(name, null);
-            }
-          },10);
-
-          return flag;
-        },
-      }),
       canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       // Check to whether trigger is disable ?
       canCreate_with_trigger_enable: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
index f0ec287f0..56ef198e1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
@@ -74,48 +74,6 @@ define('pgadmin.node.type', [
 
       },
       ext_funcs: undefined,
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          is_sys_type: false,
-          typtype: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user,
-              schemaInfo = args.node_info.schema;
-
-            this.set({
-              'typeowner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'schemaCheck',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'typeowner', label: gettext('Owner'), cell: 'string',
-          control: 'node-list-by-name',
-          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
-          disabled: 'inSchema', select2: {allowClear: false},
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }]
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['type'];
         return new TypeSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
index 393707c9b..cbfd68667 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
@@ -146,93 +146,6 @@ define('pgadmin.node.mview', [
           }
         );
       },
-      /**
-        Define model for the view node and specify the
-        properties of the model in schema.
-       */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            // Set Selected Schema and Current User
-            var schemaLabel = args.node_info.schema._label || 'public',
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'schema': schemaLabel, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          spcname: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          control: 'node-list-by-name', select2: { allowClear: false },
-          node: 'role', disabled: 'inSchema',
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-        sessChanged: function() {
-          /* If only custom autovacuum option is enabled the check if the options table is also changed. */
-          if(_.size(this.sessAttrs) == 2 && this.sessAttrs['autovacuum_custom'] && this.sessAttrs['toast_autovacuum']) {
-            return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
-          }
-          if(_.size(this.sessAttrs) == 1 && (this.sessAttrs['autovacuum_custom'] || this.sessAttrs['toast_autovacuum'])) {
-            return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
-          }
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-        validate: function(keys) {
-
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name'),
-            field_def = this.get('definition');
-
-          if(_.indexOf(keys, 'autovacuum_custom'))
-            if (_.indexOf(keys, 'autovacuum_enabled') != -1 ||
-              _.indexOf(keys, 'toast_autovacuum_enabled') != -1 )
-              return null;
-
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('name');
-          }
-          if (_.isUndefined(field_def) || _.isNull(field_def) ||
-            String(field_def).replace(/^\s+|\s+$/g, '') == '') {
-            err['definition'] = gettext('Please enter view definition.');
-            errmsg = err['definition'];
-            this.errorModel.set('definition', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('definition');
-          }
-          return null;
-        },
-        // We will disable everything if we are under catalog node
-        inSchema: function() {
-          if(this.node_info && 'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-
-      }),
 
       refresh_mview: function(args) {
         var input = args || {},
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
index b98ea6c6c..0ba952954 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
@@ -108,163 +108,6 @@ define('pgadmin.node.view', [
           }
         );
       },
-      /**
-        Define model for the view node and specify the
-        properties of the model in schema.
-      */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            // Set Selected Schema and, Current User
-            var schemaLabel = args.node_info.schema._label || 'public',
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'schema': schemaLabel, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'notInSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string', control: 'node-list-by-name',
-          node: 'role', disabled: 'notInSchema', select2: { allowClear: false },
-        },{
-          id: 'schema', label: gettext('Schema'), cell: 'string', first_empty: false,
-          control: 'node-list-by-name', type: 'text', cache_level: 'database',
-          node: 'schema', disabled: 'notInSchema', mode: ['create', 'edit'],
-          select2: { allowClear: false }, cache_node: 'database',
-        },{
-          id: 'system_view', label: gettext('System view?'), cell: 'string',
-          type: 'switch', mode: ['properties'],
-        },{
-          id: 'acl', label: gettext('Privileges'),
-          mode: ['properties'], type: 'text', group: gettext('Security'),
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'notInSchema',
-        },{
-          id: 'security_barrier', label: gettext('Security barrier?'),
-          type: 'switch', min_version: '90200', group: gettext('Definition'),
-          disabled: 'notInSchema',
-        },{
-          id: 'check_option', label: gettext('Check options'),
-          control: 'select2', group: gettext('Definition'), type: 'text',
-          min_version: '90400', mode:['properties', 'create', 'edit'],
-          select2: {
-            // Set select2 option width to 100%
-            allowClear: false,
-          }, disabled: 'notInSchema',
-          options:[{
-            label: gettext('No'), value: 'no',
-          },{
-            label: gettext('Local'), value: 'local',
-          },{
-            label: gettext('Cascaded'), value: 'cascaded',
-          }],
-        },{
-          id: 'definition', label: gettext('Code'), cell: 'string',
-          type: 'text', mode: ['create', 'edit'], group: gettext('Code'),
-          tabPanelCodeClass: 'sql-code-control',
-          disabled: 'notInSchema',
-          control: Backform.SqlCodeControl.extend({
-            onChange: function() {
-              Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
-
-              if (!this.model || !(
-                this.model.changed &&
-                this.model.node_info.server.server_type == 'pg' &&
-                // No need to check this when creating a view
-                this.model.get('oid') !== undefined
-              ) || !(
-                this.model.origSessAttrs &&
-                this.model.changed.definition != this.model.origSessAttrs.definition
-              )) {
-                this.model.warn_text = undefined;
-                return;
-              }
-
-              let old_def = this.model.origSessAttrs.definition &&
-                this.model.origSessAttrs.definition.replace(
-                  /\s/gi, ''
-                ).split('FROM'),
-                new_def = [];
-
-              if (this.model.changed.definition !== undefined) {
-                new_def = this.model.changed.definition.replace(
-                  /\s/gi, ''
-                ).split('FROM');
-              }
-
-              if ((old_def.length != new_def.length) || (
-                old_def.length > 1 && (
-                  old_def[0] != new_def[0]
-                )
-              )) {
-                this.model.warn_text = gettext(
-                  'Changing the columns in a view requires dropping and re-creating the view. This may fail if other objects are dependent upon this view, or may cause procedural functions to fail if they are not modified to take account of the changes.'
-                ) + '<br><br><b>' + gettext('Do you wish to continue?') +
-                '</b>';
-              } else {
-                this.model.warn_text = undefined;
-              }
-            },
-          }),
-        }, pgBrowser.SecurityGroupSchema, {
-          // Add Privilege Control
-          id: 'datacl', label: gettext('Privileges'), type: 'collection',
-          model: pgBrowser.Node.PrivilegeRoleModel.extend({
-            privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't'],
-          }), uniqueCol : ['grantee'], editable: false, group: 'security',
-          mode: ['edit', 'create'], canAdd: true, canDelete: true,
-          control: 'unique-col-collection', disabled: 'notInSchema',
-        },{
-          // Add Security Labels Control
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
-          canEdit: false, group: 'security', canDelete: true,
-          mode: ['edit', 'create'], canAdd: true, disabled: 'notInSchema',
-          control: 'unique-col-collection', uniqueCol : ['provider'],
-        }],
-        validate: function() {
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name'),
-            field_def = this.get('definition');
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('name');
-          }
-          if (_.isUndefined(field_def) || _.isNull(field_def) ||
-            String(field_def).replace(/^\s+|\s+$/g, '') == '') {
-            err['definition'] = gettext('Please enter view code.');
-            errmsg = err['definition'];
-            this.errorModel.set('definition', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('definition');
-          }
-          return null;
-        },
-        // We will disable everything if we are under catalog node
-        notInSchema: function() {
-          if(this.node_info && 'catalog' in this.node_info) {
-            return true;
-          }
-          return false;
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
index 344abcac5..a60fc26d9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
@@ -351,45 +351,6 @@ define('pgadmin.node.database', [
           }
         );
       },
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'did',
-        defaults: {
-          name: undefined,
-          owner: undefined,
-          comment: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'datowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [
-          {
-            id: 'name', label: gettext('Database'), cell: 'string',
-            editable: false, type: 'text',
-          },{
-            id: 'did', label: gettext('OID'), cell: 'string', mode: ['properties'],
-            editable: false, type: 'text',
-          },{
-            id: 'datowner', label: gettext('Owner'),
-            editable: false, type: 'text', node: 'role',
-            control: Backform.NodeListByNameControl, select2: { allowClear: false },
-          },{
-            id: 'comments', label: gettext('Comment'),
-            editable: false, type: 'multiline',
-          },
-        ],
-      }),
     });
 
     pgBrowser.SecurityGroupSchema = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
index 0715ea1b7..5b02716d3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
@@ -95,20 +95,20 @@ export default class DatabaseSchema extends BaseUISchema {
     return [
       {
         id: 'name', label: gettext('Database'), cell: 'text',
-        editable: false, type: 'text', noEmpty: true,
+        editable: false, type: 'text', noEmpty: true, isCollectionProperty: true,
       },{
         id: 'did', label: gettext('OID'), cell: 'text', mode: ['properties'],
         editable: false, type: 'text',
       },{
         id: 'datowner', label: gettext('Owner'),
         editable: false, type: 'select', options: this.fieldOptions.role,
-        controlProps: { allowClear: false },
+        controlProps: { allowClear: false }, isCollectionProperty: true,
       },{
         id: 'is_sys_obj', label: gettext('System database?'),
         cell: 'switch', type: 'switch', mode: ['properties'],
       },{
         id: 'comments', label: gettext('Comment'),
-        editable: false, type: 'multiline',
+        editable: false, type: 'multiline', isCollectionProperty: true,
       },{
         id: 'encoding', label: gettext('Encoding'),
         editable: false, type: 'select', group: gettext('Definition'),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
index 1a145b4d6..f5f596188 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
@@ -14,8 +14,8 @@ import Notify from '../../../../../../../static/js/helpers/Notifier';
 
 define('pgadmin.node.subscription', [
   'sources/gettext', 'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for subscriptions collection
   if (!pgBrowser.Nodes['coll-subscription']) {
@@ -24,7 +24,7 @@ define('pgadmin.node.subscription', [
         node: 'subscription',
         label: gettext('Subscriptions'),
         type: 'coll-subscription',
-        columns: ['name', 'subowner', 'pub', 'enabled'],
+        columns: ['name', 'subowner', 'proppub', 'enabled'],
         hasStatistics: true,
       });
   }
@@ -74,101 +74,6 @@ define('pgadmin.node.subscription', [
           enable: 'canCreate',
         }]);
       },
-      // Define the model for subscription node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          subowner: undefined,
-          pubtable: undefined,
-          connect_timeout: 10,
-          pub:[],
-          enabled:true,
-          create_slot: true,
-          copy_data:true,
-          connect:true,
-          copy_data_after_refresh:false,
-          sync:'off',
-          refresh_pub: false,
-          password: '',
-          sslmode: 'prefer',
-          sslcompression: false,
-          sslcert: '',
-          sslkey: '',
-          sslrootcert: '',
-          sslcrl: '',
-          host: '',
-          hostaddr: '',
-          port: 5432,
-          db: 'postgres',
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'subowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the subscription node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-          visible: function() {
-            if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
-              && !_.isUndefined(this.node_info.server.version) &&
-                this.node_info.server.version >= 100000) {
-              return true;
-            }
-            return false;
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },
-        {
-          id: 'subowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
-          disabled: function(m){
-            if(m.isNew())
-              return true;
-            return false;
-          },
-        },
-        {
-          id: 'enabled', label: gettext('Enabled?'),
-          type: 'switch', mode: ['properties'],
-          group: gettext('With'),
-          readonly: 'isConnect', deps :['connect'],
-          helpMessage: gettext('Specifies whether the subscription should be actively replicating, or whether it should be just setup but not started yet.'),
-        },
-        {
-          id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
-          mode: ['properties'],
-        },
-        ],
-        sessChanged: function() {
-          if (!this.isNew() && _.isUndefined(this.attributes['refresh_pub']))
-            return false;
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-        canCreate: function(itemData, item) {
-          var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
-            server = treeData['server'];
-
-          // If server is less than 10 then do not allow 'create' menu
-          if (server && server.version < 100000)
-            return false;
-
-          // by default we want to allow create menu
-          return true;
-        },
-      }),
       getSchema: function(treeNodeInfo, itemNodeData){
         return new SubscriptionSchema(
           {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
index bb6b418c6..771e3c03b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
@@ -176,7 +176,7 @@ export default class SubscriptionSchema extends BaseUISchema{
       mode: ['properties', 'edit', 'create'],
     },
     {
-      id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
+      id: 'proppub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
       mode: ['properties'],
     },
     {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
index f7a6baf3b..a416821da 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
@@ -1,6 +1,7 @@
 SELECT  sub.oid as oid,
         subname as name,
         subpublications as pub,
+        subpublications as proppub,
         sub.subsynccommit as sync,
         pga.rolname as subowner,
         subslotname as slot_name,
diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
index 1147e352c..0b037813c 100644
--- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
+++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
@@ -582,152 +582,6 @@ define('pgadmin.node.role', [
           },
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          oid: null,
-          rolname: undefined,
-          rolcanlogin: false,
-          rolconnlimit: -1,
-          rolsuper: false,
-          rolcreaterole: false,
-          rolcreatedb: false,
-          rolinherit: true,
-          rolcatupdate: false,
-          rolreplication: false,
-          rolvaliduntil: null,
-        },
-        schema: [{
-          id: 'rolname', label: gettext('Name'), type: 'text',
-          readonly: 'readonly',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          editable: false, type: 'text', visible: true,
-        },{
-          id: 'rolvaliduntil', readonly: 'readonly', type: 'text',
-          group: gettext('Definition'), label: gettext('Account expires'),
-          mode: ['properties', 'edit', 'create'], control: 'datetimepicker',
-          deps: ['rolcanlogin'],
-          placeholder: gettext('No Expiry'),
-          helpMessage: gettext('Please note that if you leave this field blank, then password will never expire.'),
-          setMinDate: false,
-        },{
-          id: 'rolconnlimit',  type: 'int', group: gettext('Definition'),
-          label: gettext('Connection limit'), cell: 'integer', min : -1,
-          mode: ['properties', 'edit', 'create'], readonly: 'readonly',
-        },{
-          id: 'rolcanlogin', label: gettext('Can login?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          group: gettext('Privileges'),
-          readonly: 'readonly',
-        },{
-          id: 'rolsuper', label: gettext('Superuser?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          group: gettext('Privileges'),
-          control: Backform.SwitchControl.extend({
-            onChange: function() {
-              Backform.SwitchControl.prototype.onChange.apply(this, arguments);
-
-              this.model.set('rolcatupdate', this.model.get('rolsuper'));
-              this.model.set('rolcreaterole', this.model.get('rolsuper'));
-              this.model.set('rolcreatedb', this.model.get('rolsuper'));
-            },
-          }),
-          readonly: 'readonly',
-        },{
-          id: 'rolcreaterole', label: gettext('Create roles?'),
-          group: gettext('Privileges'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'is_sys_obj', label: gettext('System role?'),
-          cell:'boolean', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comments'), type: 'multiline',
-          group: null, mode: ['properties', 'edit', 'create'],
-          readonly: 'readonly',
-        },{
-          id: 'rolcreatedb', label: gettext('Create databases?'),
-          group: gettext('Privileges'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'rolcatupdate', label: gettext('Update catalog?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          max_version: 90400,
-          group: gettext('Privileges'), readonly: function(m) {
-            return m.get('read_only');
-          },
-          disabled: function(m) {
-            return !m.get('rolsuper');
-          },
-        },{
-          id: 'rolinherit', group: gettext('Privileges'),
-          label: gettext('Inherit rights from the parent roles?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'rolreplication', group: gettext('Privileges'),
-          label: gettext('Can initiate streaming replication and backups?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          min_version: 90100,
-          readonly: 'readonly',
-        }],
-        readonly: function(m) {
-          if (!m.has('read_only')) {
-            var user = this.node_info.server.user;
-
-            m.set('read_only', !(user.is_superuser || user.can_create_role));
-          }
-
-          return m.get('read_only');
-        },
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('rolname')) || String(this.get('rolname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js
index 9f944ff19..240665432 100644
--- a/web/pgadmin/browser/static/js/collection.js
+++ b/web/pgadmin/browser/static/js/collection.js
@@ -7,8 +7,9 @@
 //
 //////////////////////////////////////////////////////////////
 
-import {removeNodeView} from './node_view';
-import Notify from '../../../static/js/helpers/Notifier';
+// import {removeNodeView} from './node_view';
+// import Notify from '../../../static/js/helpers/Notifier';
+import {getPanelView} from './panel_view';
 
 define([
   'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin',
@@ -91,399 +92,14 @@ define([
       canDropCascade: true,
       selectParentNodeOnDelete: false,
       showProperties: function(item, data, panel) {
-        var that = this,
-          j = panel.$container.find('.obj_properties').first(),
-          view = j.data('obj-view'),
-          content = $('<div></div>')
-            .addClass('pg-prop-content col-12 has-pg-prop-btn-group'),
-          node = pgBrowser.Nodes[that.node],
-          $msgContainer = '',
-          // This will be the URL, used for object manipulation.
-          urlBase = this.generate_url(item, 'properties', data),
-          info = pgBrowser.tree.getTreeNodeHierarchy(item),
-          gridSchema = Backform.generateGridColumnsFromModel(
-            info, node.model, 'properties', that.columns
-          ),
-          createButtons = function(buttonsList, location, extraClasses) {
-            // Arguments must be non-zero length array of type
-            // object, which contains following attributes:
-            // label, type, extraClasses, register
-            if (buttonsList && _.isArray(buttonsList) && buttonsList.length > 0) {
-              // All buttons will be created within a single
-              // div area.
-              var btnGroup =
-                $('<div class="pg-prop-btn-group"></div>'),
-                // Template used for creating a button
-                tmpl = _.template([
-                  '<button tabindex="0" type="<%= type %>" ',
-                  'class="btn <%=extraClasses.join(\' \')%>"',
-                  '<% if (disabled) { %> disabled="disabled"<% } %> title="<%-tooltip%>">',
-                  '<span class="<%= icon %>" role="img"></span><% if (label != "") { %>&nbsp;<%-label%><% } %><span class="sr-only"><%-tooltip%></span></button>',
-                ].join(' '));
-              if (location == 'header') {
-                btnGroup.appendTo(that.header);
-              } else {
-                btnGroup.appendTo(that.footer);
-              }
-              if (extraClasses) {
-                btnGroup.addClass(extraClasses);
-              }
-              _.each(buttonsList, function(btn) {
-                // Create the actual button, and append to
-                // the group div
 
-                // icon may not present for this button
-                if (!btn.icon) {
-                  btn.icon = '';
-                }
-                var b = $(tmpl(btn));
-                btnGroup.append(b);
-                // Register is a callback to set callback
-                // for certain operation for this button.
-                btn.register(b);
-              });
-              return btnGroup;
-            }
-            return null;
-          }.bind(panel);
-
-        that.collection = new (node.Collection.extend({
-          url: urlBase,
-          model: node.model,
-        }))();
-        // Add the new column for the multi-select menus
-        if((_.isFunction(that.canDrop) ?
-          that.canDrop.apply(that, [data, item]) : that.canDrop) ||
-              (_.isFunction(that.canDropCascade) ?
-                that.canDropCascade.apply(that, [data, item]) : that.canDropCascade)) {
-          gridSchema.columns.unshift({
-            name: 'oid',
-            cell: Backgrid.Extension.SelectRowCell.extend({
-              initialize: function (options) {
-                this.column = options.column;
-                if (!(this.column instanceof Backgrid.Column)) {
-                  this.column = new Backgrid.Column(this.column);
-                }
-
-                var column = this.column, model = this.model, $el = this.$el;
-                this.listenTo(column, 'change:renderable', function (col, renderable) {
-                  $el.toggleClass('renderable', renderable);
-                });
-
-                if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass('renderable width_percent_3');
-
-                this.listenTo(model, 'backgrid:select', this.toggleCheckbox);
-              },
-              toggleCheckbox: function(model, selected) {
-                if (this.checkbox().prop('disabled') === false) {
-                  this.checkbox().prop('checked', selected).change();
-                }
-              },
-              render: function() {
-                let model = this.model.toJSON();
-                // canDrop can be set to false for individual row from the server side to disable the checkbox
-                let disabled = ('canDrop' in model && model.canDrop === false);
-                let id = `row-${_.uniqueId(model.oid || model.name)}`;
-
-                this.$el.empty().append(`
-                  <div class="custom-control custom-checkbox custom-checkbox-no-label">
-                    <input tabindex="-1" type="checkbox" class="custom-control-input" id="${id}" ${disabled?'disabled':''}/>
-                    <label class="custom-control-label" for="${id}">
-                      <span class="sr-only">` + gettext('Select') + `<span>
-                    </label>
-                  </div>
-                `);
-                this.delegateEvents();
-                return this;
-              },
-            }),
-            headerCell: Backgrid.Extension.SelectAllHeaderCell,
-          });
-        }
-        /* Columns should be always non-editable  */
-        gridSchema.columns.forEach((col)=>{
-          col.disabled = true;
-        });
-
-        // Get the list of selected models, before initializing the grid
-        // again.
-        var selectedModels = [];
-        if(!_.isUndefined(that.grid) && 'collection' in that.grid){
-          selectedModels = that.grid.getSelectedModels();
-        }
-
-        // Initialize a new Grid instance
-        that.grid = new Backgrid.Grid({
-          emptyText: gettext('No data found'),
-          columns: gridSchema.columns,
-          collection: that.collection,
-          className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
-        });
-
-        var gridView = {
-          'remove': function() {
-            if (this.grid) {
-              if (this.grid.collection) {
-                this.grid.collection.reset([], {silent: true});
-                delete (this.grid.collection);
-              }
-              delete (this.grid);
-              this.grid = null;
-            }
-          },
-          grid: that.grid,
-        };
-
-        if (view) {
-          // Cache the current IDs for next time
-          $(panel).data('node-prop', urlBase);
-
-          // Reset the data object
-          j.data('obj-view', null);
-        }
-
-        /* Remove any dom rendered by getNodeView */
-        removeNodeView(j[0]);
-        // Make sure the HTML element is empty.
-        j.empty();
-        j.data('obj-view', gridView);
-
-        $msgContainer = '<div role="status" class="pg-panel-message pg-panel-properties-message">' +
-         gettext('Retrieving data from the server...') + '</div>';
-
-        $msgContainer = $($msgContainer).appendTo(j);
-
-        that.header = $('<div></div>').addClass(
-          'pg-prop-header'
+        let container =  panel.$container[0];
+        getPanelView(
+          pgBrowser.tree,
+          container,
+          pgBrowser,
+          panel._type
         );
-
-        // Render the buttons
-        var buttons = [];
-
-        buttons.push({
-          label: '',
-          type: 'delete',
-          tooltip: gettext('Delete/Drop'),
-          extraClasses: ['btn-primary-icon m-1', 'delete_multiple'],
-          icon: 'fa fa-trash-alt',
-          disabled:  (_.isFunction(that.canDrop)) ? !(that.canDrop.apply(self, [data, item])) : (!that.canDrop),
-          register: function(btn) {
-            btn.on('click',() => {
-              onDrop('drop');
-            });
-          },
-        });
-
-        buttons.push({
-          label: '',
-          type: 'delete',
-          tooltip: gettext('Drop Cascade'),
-          extraClasses: ['btn-primary-icon m-1', 'delete_multiple_cascade'],
-          icon: 'pg-font-icon icon-drop_cascade',
-          disabled: (_.isFunction(that.canDropCascade)) ? !(that.canDropCascade.apply(self, [data, item])) : (!that.canDropCascade),
-          register: function(btn) {
-            btn.on('click',() => {
-              onDrop('dropCascade');
-            });
-          },
-        });
-
-        createButtons(buttons, 'header', 'pg-prop-btn-group-above');
-
-        // Render subNode grid
-        content.append('<div class="pg-prop-coll-container"></div>');
-        content.find('.pg-prop-coll-container').append(that.grid.render().$el);
-
-        var timer;
-        var getAjaxHook = function() {
-          $.ajax({
-            url: urlBase,
-            type: 'GET',
-            beforeSend: function(xhr) {
-              xhr.setRequestHeader(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
-              // Generate a timer for the request
-              timer = setTimeout(function() {
-                // notify user if request is taking longer than 1 second
-
-                if (!$msgContainer.text()== 'Failed to retrieve data from the server.')
-                  $msgContainer.text(gettext('Retrieving data from the server...'));
-                $msgContainer.removeClass('d-none');
-                if (self.grid) {
-                  self.grid.remove();
-                }
-              }, 1000);
-            },
-          }).done(function(res) {
-            clearTimeout(timer);
-
-            if (_.isUndefined(that.grid) || _.isNull(that.grid)) return;
-
-            that.data = res;
-
-            if (that.data.length > 0) {
-
-              if (!$msgContainer.hasClass('d-none')) {
-                $msgContainer.addClass('d-none');
-              }
-              that.header.appendTo(j);
-              j.append(content);
-
-              // Listen scroll event to load more rows
-              $('.pg-prop-content').on('scroll', that.__loadMoreRows.bind(that));
-
-              that.collection.reset(that.data.splice(0, 50));
-
-              // Listen to select all checkbox event
-              that.collection.on('backgrid:select-all', that.__loadAllRows.bind(that));
-
-              // Trigger the backgrid:select event for already selected items
-              // as we have created a new grid instance.
-              if(selectedModels.length > 0) {
-                that.collection.each(function (model) {
-                  for(let model_val of selectedModels){
-                    if (model_val.id == model.id){
-                      model.trigger('backgrid:select', model, true);
-                    }
-                  }
-                });
-              }
-            } else {
-            // Do not listen the scroll event
-              $('.pg-prop-content').off('scroll', that.__loadMoreRows);
-
-              $msgContainer.text(gettext('No properties are available for the selected object.'));
-
-            }
-            selectedModels = [];
-          }).fail(function(xhr, error) {
-            pgBrowser.Events.trigger(
-              'pgadmin:node:retrieval:error', 'properties', xhr, error.message, item, that
-            );
-            if (!Alertify.pgHandleItemError(xhr, error.message, {
-              item: item,
-              info: info,
-            })) {
-              Notify.pgNotifier(
-                error, xhr, gettext('Error retrieving properties - %s', error.message || that.label),
-                function(msg) {
-                  if(msg === 'CRYPTKEY_SET') {
-                    getAjaxHook();
-                  } else {
-                    console.warn(arguments);
-                  }
-                }
-              );
-            }
-            // show failed message.
-            $msgContainer.text(gettext('Failed to retrieve data from the server.'));
-          });
-        };
-        getAjaxHook();
-
-        var onDrop = function(type, confirm=true) {
-          let sel_row_models = this.grid.getSelectedModels(),
-            sel_rows = [],
-            sel_item = pgBrowser.tree.selected(),
-            d = sel_item ? pgBrowser.tree.itemData(sel_item) : null,
-            sel_node = d && pgBrowser.Nodes[d._type],
-            url = undefined,
-            msg = undefined,
-            title = undefined;
-
-          if (sel_node && sel_node.type && sel_node.type == 'coll-constraints') {
-            // In order to identify the constraint type, the type should be passed to the server
-            sel_rows = sel_row_models.map(row => ({id: row.get('oid'), _type: row.get('_type')}));
-          }
-          else {
-            sel_rows = sel_row_models.map(row => row.id);
-          }
-
-          if (sel_rows.length === 0) {
-            Notify.alert(gettext('Drop Multiple'),
-              gettext('Please select at least one object to delete.')
-            );
-            return;
-          }
-
-          if (!sel_node)
-            return;
-
-          if (type === 'dropCascade') {
-            url = sel_node.generate_url(sel_item, 'delete');
-            msg = gettext('Are you sure you want to drop all the selected objects and all the objects that depend on them?');
-            title = gettext('DROP CASCADE multiple objects?');
-          } else {
-            url = sel_node.generate_url(sel_item, 'drop');
-            msg = gettext('Are you sure you want to drop all the selected objects?');
-            title = gettext('DROP multiple objects?');
-          }
-
-          let dropAjaxHook = function() {
-            $.ajax({
-              url: url,
-              type: 'DELETE',
-              data: JSON.stringify({'ids': sel_rows}),
-              contentType: 'application/json; charset=utf-8',
-            }).done(function(res) {
-              if (res.success == 0) {
-                pgBrowser.report_error(res.errormsg, res.info);
-              } else {
-                $(pgBrowser.panels['properties'].panel).removeData('node-prop');
-                pgBrowser.Events.trigger(
-                  'pgadmin:browser:tree:refresh', sel_item || pgBrowser.tree.selected(), {
-                    success: function() {
-                      setTimeout(function() {
-                        pgBrowser.tree.select(sel_item);
-                        sel_node.callbacks.selected.apply(sel_node, [sel_item]);
-                      }, 100);
-                    },
-                  });
-              }
-              return true;
-            }).fail(function(xhr, error) {
-              Notify.pgNotifier(
-                error, xhr,
-                gettext('Error dropping %s', d._label.toLowerCase()),
-                function(alertMsg) {
-                  if (alertMsg == 'CRYPTKEY_SET') {
-                    onDrop(type, false);
-                  } else {
-                    $(pgBrowser.panels['properties'].panel).removeData('node-prop');
-                    pgBrowser.Events.trigger(
-                      'pgadmin:browser:tree:refresh', sel_item || pgBrowser.tree.selected(), {
-                        success: function() {
-                          sel_node.callbacks.selected.apply(sel_node, [sel_item]);
-                        },
-                      }
-                    );
-                  }
-                }
-              );
-            });
-          };
-
-          if(confirm) {
-            Notify.confirm(title, msg, dropAjaxHook, null);
-          } else {
-            dropAjaxHook();
-          }
-        }.bind(that);
-      },
-      __loadMoreRows: function(e) {
-        let elem = e.currentTarget;
-        if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
-          if (this.data.length > 0) {
-            this.collection.add(this.data.splice(0, 50));
-          }
-        }
-      },
-      __loadAllRows: function(tmp, checked) {
-        if (this.data.length > 0) {
-          this.collection.add(this.data);
-          this.collection.each(function (model) {
-            model.trigger('backgrid:select', model, checked);
-          });
-        }
       },
       generate_url: function(item, type) {
         /*
diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index 9e6d3d543..21ae4c06d 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -1082,8 +1082,6 @@ define('pgadmin.browser.node', [
             b.panels['properties'] &&
             b.panels['properties'].panel &&
             b.panels['properties'].panel.isVisible()) {
-            // Show object properties (only when the 'properties' tab
-            // is active).
             this.showProperties(item, d, b.panels['properties'].panel);
           }
         }
@@ -1259,20 +1257,20 @@ define('pgadmin.browser.node', [
             d = i && tree.itemData(i),
             treeHierarchy = tree.getTreeNodeHierarchy(i);
 
-          if (_.isEqual($(this).data('node-prop'), treeHierarchy)) {
-            return;
-          }
-
           // Cache the current IDs for next time
           $(this).data('node-prop', treeHierarchy);
 
           /* Remove any dom rendered by getNodeView */
-          removeNodeView(j[0]);
-          /* getSchema is a schema for React. Get the react node view */
+          removeNodeView(pgBrowser.panels['properties'].panel.$container[0]);
+
+          var containerProperties =  pgBrowser.panels['properties'].panel.$container;
+          containerProperties.addClass('pg-panel-content pg-no-overflow pg-el-container');
+
+
           if(that.getSchema) {
             let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
             getNodeView(
-              that.type, treeNodeInfo, 'properties', data, 'tab', j[0], this, onEdit
+              that.type, treeNodeInfo, 'properties', data, 'tab', containerProperties[0], this, onEdit
             );
             return;
           }
diff --git a/web/pgadmin/browser/static/js/node_ajax.js b/web/pgadmin/browser/static/js/node_ajax.js
index 14a9afa3c..19ac76562 100644
--- a/web/pgadmin/browser/static/js/node_ajax.js
+++ b/web/pgadmin/browser/static/js/node_ajax.js
@@ -25,8 +25,9 @@ export function generateCollectionURL(item, type) {
   };
   var treeInfo = pgAdmin.Browser.tree.getTreeNodeHierarchy(item);
   var actionType = type in opURL ? opURL[type] : type;
+  var nodeType = type === 'properties' ? nodeObj.type : nodeObj.node;
   return generate_url(
-    pgAdmin.Browser.URL, treeInfo, actionType, nodeObj.node,
+    pgAdmin.Browser.URL, treeInfo, actionType, nodeType,
     collectionPickFunction
   );
 }
diff --git a/web/pgadmin/browser/static/js/node_view.jsx b/web/pgadmin/browser/static/js/node_view.jsx
index b9ec79e90..453f20c95 100644
--- a/web/pgadmin/browser/static/js/node_view.jsx
+++ b/web/pgadmin/browser/static/js/node_view.jsx
@@ -16,7 +16,6 @@ import {getHelpUrl, getEPASHelpUrl} from 'pgadmin.help';
 import SchemaView from 'sources/SchemaView';
 import { generateNodeUrl } from './node_ajax';
 import Notify from '../../../static/js/helpers/Notifier';
-
 import gettext from 'sources/gettext';
 import 'wcdocker';
 
diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js
index fbbc56bd5..c9d1b1f84 100644
--- a/web/pgadmin/browser/static/js/panel.js
+++ b/web/pgadmin/browser/static/js/panel.js
@@ -122,14 +122,32 @@ define(
                 that.resizedContainer.apply(myPanel);
               }
 
-              // Bind events only if they are configurable
-              if (that.canHide) {
-                _.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
-                  function(ev) {
-                    myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
-                  });
+
+
+              if (myPanel._type == 'dashboard') {
+                getPanelView(
+                  pgBrowser.tree,
+                  $container[0],
+                  pgBrowser,
+                  myPanel._type
+                );
               }
 
+              // Rerender the dashboard panel when preference value 'show graph' gets changed.
+              pgBrowser.onPreferencesChange('dashboards', function() {
+                getPanelView(
+                  pgBrowser.tree,
+                  $container[0],
+                  pgBrowser,
+                  myPanel._type
+                );
+              });
+              
+              _.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
+                function(ev) {
+                  myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
+                });
+
               pgBrowser.Events.on('pgadmin-browser:tree:selected', () => {
 
                 if(myPanel.isVisible()) {
@@ -141,6 +159,18 @@ define(
                   );
                 }
               });
+
+              pgBrowser.Events.on('pgadmin-browser:tree:refreshing', () => {
+
+                if(myPanel.isVisible()) {
+                  getPanelView(
+                    pgBrowser.tree,
+                    $container[0],
+                    pgBrowser,
+                    myPanel._type
+                  );
+                }
+              });
             },
           });
         }
@@ -205,11 +235,6 @@ define(
         }
       },
       handleVisibility: function(eventName) {
-        // Supported modules
-        let type_module = {
-          dashboard: pgAdmin.Dashboard,
-        };
-        let module = type_module[this._type];
         if (_.isNull(pgBrowser.tree)) return;
 
         let selectedPanel = pgBrowser.docker.findPanels(this._type)[0];
@@ -219,18 +244,6 @@ define(
           .scene()
           .find('.pg-panel-content');
 
-        if (this._type === 'dashboard') {
-          if (eventName == 'panelClosed') {
-            module.toggleVisibility.call(module, false, true);
-          } else if (eventName == 'panelVisibilityChanged') {
-            module.toggleVisibility.call(
-              module,
-              pgBrowser.docker.findPanels(this._type)[0].isVisible(),
-              false
-            );
-          }
-        }
-
         if (isPanelVisible) {
           if (eventName == 'panelClosed') {
             removePanelView($container[0]);
diff --git a/web/pgadmin/browser/static/js/panel_view.jsx b/web/pgadmin/browser/static/js/panel_view.jsx
index cf0a5a07e..2ada1e375 100644
--- a/web/pgadmin/browser/static/js/panel_view.jsx
+++ b/web/pgadmin/browser/static/js/panel_view.jsx
@@ -13,6 +13,11 @@ import Theme from 'sources/Theme';
 import Dependencies from '../../../misc/dependencies/static/js/Dependencies';
 import Dependents from '../../../misc/dependents/static/js/Dependents';
 import Statistics from '../../../misc/statistics/static/js/Statistics';
+import SQL from '../../../misc/sql/static/js/SQL';
+import Dashboard from '../../../dashboard/static/js/Dashboard';
+import _ from 'lodash';
+import { CollectionNodeView } from '../../../misc/properties/CollectionNodeProperties';
+
 
 /* The entry point for rendering React based view in properties, called in node.js */
 export function getPanelView(
@@ -21,10 +26,33 @@ export function getPanelView(
   pgBrowser,
   panelType
 ) {
-  let item = tree.selected(),
-    nodeData = item && tree.itemData(item),
-    node = item && nodeData && pgBrowser.Nodes[nodeData._type],
+  let item = !_.isNull(tree)? tree.selected(): null,
+
+    nodeData, node, treeNodeInfo, preferences;
+  if (item){
+    nodeData = tree.itemData(item);
+    node = nodeData && pgBrowser.Nodes[nodeData._type];
     treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
+    preferences = pgBrowser.get_preferences_for_module('dashboards');
+  }
+  if (panelType == 'dashboard') {
+    ReactDOM.render(
+      <Theme>
+        <Dashboard
+          treeNodeInfo={treeNodeInfo}
+          pgBrowser={pgBrowser}
+          nodeData={nodeData}
+          node={node}
+          item={item}
+          preferences={preferences}
+          did={((!_.isUndefined(treeNodeInfo)) && (!_.isUndefined(treeNodeInfo['database']))) && treeNodeInfo['database']._id}
+          sid={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo['server']._id : ''}
+          serverConnected={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo.server.connected: false}
+        />
+      </Theme>,
+      container
+    );
+  }
 
 
   if (panelType == 'statistics') {
@@ -41,6 +69,20 @@ export function getPanelView(
       container
     );
   }
+  if (panelType == 'properties') {
+    ReactDOM.render(
+      <Theme>
+        <CollectionNodeView
+          treeNodeInfo={treeNodeInfo}
+          item={item}
+          itemNodeData={nodeData}
+          node={node}
+          pgBrowser={pgBrowser}
+        />
+      </Theme>,
+      container
+    );
+  }
   if (panelType == 'dependencies') {
     ReactDOM.render(
       <Theme>
@@ -69,6 +111,20 @@ export function getPanelView(
       container
     );
   }
+  if (panelType == 'sql') {
+    ReactDOM.render(
+      <Theme>
+        <SQL
+          treeNodeInfo={treeNodeInfo}
+          pgBrowser={pgBrowser}
+          nodeData={nodeData}
+          node={node}
+          item={item}
+        />
+      </Theme>,
+      container
+    );
+  }
 }
 
 /* When switching from normal node to collection node, clean up the React mounted DOM */
diff --git a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
new file mode 100644
index 000000000..79b8146cc
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
@@ -0,0 +1,63 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+
+export default class ActiveQuery extends BaseUISchema {
+  constructor(initValues) {
+    super({
+      ...initValues,
+    });
+
+  }
+
+  get baseFields() {
+    return [
+
+      {
+        id: 'backend_type',
+        label: gettext('Backend type'),
+        type: 'text',
+        editable: true,
+        noEmpty: true,
+        readonly: true,
+        mode: ['properties'],
+        group: gettext('Details'),
+      },
+      {
+        id: 'query_start',
+        label: gettext('Query started at'),
+        type: 'text',
+        editable: false,
+        readonly: true,
+        group: gettext('Details'),
+      },
+      {
+        id: 'state_change',
+        label: gettext('Last state changed at'),
+        type: 'text',
+        editable: false,
+        readonly: true,
+        group: gettext('Details'),
+      },
+      {
+        id: 'query',
+        label: gettext('SQL'),
+        cell: 'string',
+        editable: false,
+        readonly: true,
+        type: 'sql',
+        group: gettext('Details'),
+      },
+    ];
+
+  }
+
+}
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
new file mode 100644
index 000000000..616d65af3
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -0,0 +1,828 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+// eslint-disable-next-line react/display-name
+import React, { useEffect, useState } from 'react';
+import gettext from 'sources/gettext';
+import PropTypes from 'prop-types';
+import getApiInstance from 'sources/api_instance';
+import PgTable from 'sources/components/PgTable';
+import { makeStyles } from '@material-ui/core/styles';
+import url_for from 'sources/url_for';
+import Graphs from './Graphs';
+import Notify from '../../../static/js/helpers/Notifier';
+import { Box, Tab, Tabs } from '@material-ui/core';
+import { PgIconButton } from '../../../static/js/components/Buttons';
+import CancelIcon from '@mui/icons-material/Cancel';
+import SquareIcon from '@mui/icons-material/Square';
+import ArrowRightOutlinedIcon from '@mui/icons-material/ArrowRightOutlined';
+import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';
+import WelcomeDashboard from './WelcomeDashboard';
+import ActiveQuery from './ActiveQuery.ui';
+
+function parseData(data) {
+  var res = [];
+
+  data.forEach((row) => {
+    res.push({ ...row, icon: '' });
+  });
+  return res;
+}
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    height: '100%',
+    background: theme.palette.grey[400],
+    overflow: 'hidden',
+    padding: '8px',
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+  },
+
+  cardHeader: {
+    padding: '0.25rem 0.5rem',
+    fontWeight: 'bold',
+    backgroundColor: theme.otherVars.tableBg,
+    borderBottom: '1px solid',
+    borderBottomColor: theme.otherVars.borderColor,
+  },
+  searchPadding: {
+    display: 'flex',
+    flex: 2.5,
+  },
+  component: {
+    padding: '8px',
+  },
+  searchInput: {
+    flex: 1,
+  },
+  panelIcon: {
+    width: '80%',
+    margin: '0 auto',
+    marginTop: '25px !important',
+    position: 'relative',
+    textAlign: 'center',
+  },
+  panelMessage: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+  },
+  panelContent: {
+    margin: 0,
+    border: '2px solid #dde0e6',
+    flexDirection: 'column',
+    flexGrow: 1,
+    overflow: 'hidden !important',
+  },
+  terminateButton: {
+    color: theme.palette.error.main
+  }
+}));
+
+/* eslint-disable react/display-name */
+export default function Dashboard({
+  nodeData,
+  node,
+  item,
+  pgBrowser,
+  preferences,
+  sid,
+  did,
+  ...props
+}) {
+  const classes = useStyles();
+  let tab = ['Sessions', 'Lock', 'Prepared Transactions'];
+
+  const [dashData, setdashData] = useState([]);
+  const [msg, setMsg] = useState('');
+  const [val, setVal] = useState(0);
+  const [schema, setSchema] = React.useState();
+ 
+  if (!did) {
+    tab.push('Configuration');
+  }
+
+  const tabChanged = (e, tabVal) => {
+    setVal(tabVal);
+  };
+
+  const serverConfigColumns = React.useMemo(
+    () => [
+      {
+        accessor: 'name',
+        Header: gettext('Name'),
+        sortble: true,
+        resizable: true,
+        disableGlobalFilter: false,
+      },
+      {
+        accessor: 'category',
+        Header: gettext('Category'),
+        sortble: true,
+        resizable: true,
+        disableGlobalFilter: false,
+      },
+      {
+        accessor: 'setting',
+        Header: gettext('Setting'),
+        sortble: true,
+        resizable: true,
+        disableGlobalFilter: false,
+      },
+      {
+        accessor: 'unit',
+        Header: gettext('Unit'),
+        editable: false,
+        cell: 'string',
+      },
+      {
+        accessor: 'short_desc',
+        Header: gettext('Description'),
+        sortble: true,
+        resizable: false,
+        disableGlobalFilter: false,
+      },
+    ],
+    [val]
+  );
+
+  const activityColumns = [
+    {
+      accessor: 'terminate_query',
+      Header: ' ',
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 16,
+      maxWidth: 30,
+      // eslint-disable-next-line react/display-name
+      Cell: ({ row }) => {
+        var terminate_session_url =
+          url_for('dashboard.index') + 'terminate_session' + '/' + sid,
+          title = gettext('Terminate Session?'),
+          txtConfirm = gettext(
+            'Are you sure you wish to terminate the session?'
+          ),
+          txtSuccess = gettext('Session terminated successfully.'),
+          txtError = gettext(
+            'An error occurred whilst terminating the active query.'
+          ),
+          action_url = did
+            ? terminate_session_url + '/' + did
+            : terminate_session_url;
+
+        const api = getApiInstance();
+
+        return (
+          <PgIconButton
+            size="xs"
+            noBorder
+            icon={<CancelIcon />}
+            className={classes.terminateButton}
+            onClick={() => {
+              if (
+                !canTakeAction(row, 'terminate', nodeData, props.treeNodeInfo)
+              )
+                return;
+              action_url += '/' + row.values.pid;
+              Notify.confirm(
+                title,
+                txtConfirm,
+                function () {
+                  api
+                    .delete(action_url)
+                    .then(function (res) {
+                      if (res == gettext('Success')) {
+                        Notify.success(txtSuccess);
+                      } else {
+                        Notify.error(txtError);
+                      }
+                    })
+                    .catch(function (error) {
+                      Notify.alert(
+                        gettext('Failed to retrieve data from the server.'),
+                        gettext(error.message)
+                      );
+                    });
+                },
+                function () {
+                  return true;
+                }
+              );
+            }}
+            color="default"
+            aria-label="Terminate Session?"
+            title={gettext('Terminate Session?')}
+          ></PgIconButton>
+        );
+      },
+    },
+    {
+      accessor: 'cancel_Query',
+      Header: ' ',
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 16,
+      maxWidth: 30,
+      Cell: ({ row }) => {
+        var cancel_query_url =
+          url_for('dashboard.index') + 'cancel_query' + '/' + sid,
+          title = gettext('Cancel Active Query?'),
+          txtConfirm = gettext(
+            'Are you sure you wish to cancel the active query?'
+          ),
+          txtSuccess = gettext('Active query cancelled successfully.'),
+          txtError = gettext(
+            'An error occurred whilst cancelling the active query.'
+          ),
+          action_url = did ? cancel_query_url + '/' + did : cancel_query_url;
+
+        const api = getApiInstance();
+
+        return (
+          <PgIconButton
+            size="xs"
+            noBorder
+            icon={<SquareIcon fontSize="small" />}
+            onClick={() => {
+              if (!canTakeAction(row, 'cancel', nodeData, props.treeNodeInfo))
+                return;
+              action_url += '/' + row.values.pid;
+              Notify.confirm(
+                title,
+                txtConfirm,
+                function () {
+                  api
+                    .delete(action_url)
+                    .then(function (res) {
+                      if (res == gettext('Success')) {
+                        Notify.success(txtSuccess);
+                      } else {
+                        Notify.error(txtError);
+                      }
+                    })
+                    .catch(function (error) {
+                      Notify.alert(
+                        gettext('Failed to retrieve data from the server.'),
+                        gettext(error.message)
+                      );
+                    });
+                },
+                function () {
+                  return true;
+                }
+              );
+            }}
+            color="default"
+            aria-label="Cancel the query"
+            title={gettext('Cancel the active query')}
+          ></PgIconButton>
+        );
+      },
+    },
+    {
+      accessor: 'view_active_query',
+      Header: ' ',
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 16,
+      maxWidth: 30,
+      Cell: ({ row }) => {
+        let canEditRow = true;
+        return (
+          <PgIconButton
+            icon={
+              row.isExpanded ? (
+                <ArrowDropDownOutlinedIcon />
+              ) : (
+                <ArrowRightOutlinedIcon />
+              )
+            }
+            size="xs"
+            noBorder
+            onClick={() => {
+              row.toggleRowExpanded(!row.isExpanded);
+              setSchema(
+                new ActiveQuery({
+                  query: row.original.query,
+                  backend_type: row.original.backend_type,
+                  state_change: row.original.state_change,
+                  query_start: row.original.query_start,
+                })
+              );
+            }}
+            disabled={!canEditRow}
+            aria-label="View the active session details"
+            title={gettext('View the active session details')}
+          />
+        );
+      },
+    },
+    {
+      accessor: 'pid',
+      Header: gettext('PID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'usename',
+      Header: gettext('User'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 80,
+    },
+    {
+      accessor: 'application_name',
+      Header: gettext('Application'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'client_addr',
+      Header: gettext('Client'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'backend_start',
+      Header: gettext('Backend start'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'xact_start',
+      Header: gettext('Transaction start'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'state',
+      Header: gettext('State'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+
+    {
+      accessor: 'waiting',
+      Header: gettext('Waiting'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'wait_event',
+      Header: gettext('Wait event'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'blocking_pids',
+      Header: gettext('Blocking PIDs'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const databaseLocksColumns = [
+    {
+      accessor: 'pid',
+      Header: gettext('PID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'locktype',
+      Header: gettext('Lock type'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'relation',
+      Header: gettext('Target relation'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'page',
+      Header: gettext('Page'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'tuple',
+      Header: gettext('Tuple'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'virtualxid',
+      Header: gettext('vXID (target)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'transactionid',
+      Header: gettext('XID (target)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'classid',
+      Header: gettext('Class'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 40,
+    },
+    {
+      accessor: 'objid',
+      Header: gettext('Object ID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'virtualtransaction',
+      Header: gettext('vXID (owner)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'mode',
+      Header: gettext('Mode'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'granted',
+      Header: gettext('Granted?'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const databasePreparedColumns = [
+    {
+      accessor: 'git',
+      Header: gettext('Name'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'Owner',
+      Header: gettext('Owner'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'transaction',
+      Header: gettext('XID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'prepared',
+      Header: gettext('Prepared at'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const canTakeAction = (row, cellAction, itemNodeData, treeNodeInfo) => {
+    // We will validate if user is allowed to cancel the active query
+    // If there is only one active session means it probably our main
+    // connection session
+    cellAction = cellAction || null;
+    var pg_version = treeNodeInfo.server.version || null,
+      is_cancel_session = cellAction === 'cancel',
+      txtMessage,
+      maintenance_database = treeNodeInfo.server.db,
+      is_super_user,
+      current_user;
+
+    var can_signal_backend =
+      treeNodeInfo.server && treeNodeInfo.server.user
+        ? treeNodeInfo.server.user.can_signal_backend
+        : false;
+
+    if (
+      treeNodeInfo.server &&
+      treeNodeInfo.server.user &&
+      treeNodeInfo.server.user.is_superuser
+    ) {
+      is_super_user = true;
+    } else {
+      is_super_user = false;
+      current_user =
+        treeNodeInfo.server && treeNodeInfo.server.user
+          ? treeNodeInfo.server.user.name
+          : null;
+    }
+
+    // With PG10, We have background process showing on dashboard
+    // We will not allow user to cancel them as they will fail with error
+    // anyway, so better usability we will throw our on notification
+
+    // Background processes do not have database field populated
+    if (pg_version && pg_version >= 100000 && !row.original.datname) {
+      if (is_cancel_session) {
+        txtMessage = gettext('You cannot cancel background worker processes.');
+      } else {
+        txtMessage = gettext(
+          'You cannot terminate background worker processes.'
+        );
+      }
+      Notify.info(txtMessage);
+      return false;
+      // If it is the last active connection on maintenance db then error out
+    } else if (
+      maintenance_database == row.original.datname &&
+      row.original.state == 'active'
+    ) {
+      if (is_cancel_session) {
+        txtMessage = gettext(
+          'You are not allowed to cancel the main active session.'
+        );
+      } else {
+        txtMessage = gettext(
+          'You are not allowed to terminate the main active session.'
+        );
+      }
+      Notify.error(txtMessage);
+      return false;
+    } else if (is_cancel_session && row.original.state == 'idle') {
+      // If this session is already idle then do nothing
+      Notify.info(gettext('The session is already in idle state.'));
+      return false;
+    } else if (can_signal_backend) {
+      // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
+      return true;
+    } else if (is_super_user) {
+      // Super user can do anything
+      return true;
+    } else if (current_user && current_user == treeNodeInfo.server.user) {
+      // Non-super user can cancel only their active queries
+      return true;
+    } else {
+      // Do not allow to cancel someone else session to non-super user
+      if (is_cancel_session) {
+        txtMessage = gettext(
+          'Superuser privileges are required to cancel another users query.'
+        );
+      } else {
+        txtMessage = gettext(
+          'Superuser privileges are required to terminate another users query.'
+        );
+      }
+      Notify.error(txtMessage);
+      return false;
+    }
+  };
+
+  useEffect(() => {
+    let url,
+      message = gettext(
+        'Please connect to the selected server to view the dashboard.'
+      );
+
+    if (sid && props.serverConnected) {
+      if (val === 0) {
+        url = url_for('dashboard.activity');
+      } else if (val === 1) {
+        url = url_for('dashboard.locks');
+      } else if (val === 2) {
+        url = url_for('dashboard.prepared');
+      } else {
+        url = url_for('dashboard.config');
+      }
+
+      message = gettext('Loading dashboard...');
+      if (did) url += sid + '/' + did;
+      else url += sid;
+
+      const api = getApiInstance();
+      if (node) {
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            setdashData(parseData(res.data));
+          })
+          .catch((e) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(e.message)
+            );
+            // show failed message.
+            setMsg(gettext('Failed to retrieve data from the server.'));
+          });
+      } else {
+        setMsg(message);
+      }
+    }
+    if (message != '') {
+      setMsg(message);
+    }
+  }, [nodeData, val, did, preferences]);
+
+  return (
+    <>
+      {sid && props.serverConnected ? (
+        <Box className={classes.emptyPanel}>
+          {!_.isUndefined(preferences) && preferences.show_graphs && (
+            <Graphs
+              preferences={preferences}
+              sid={sid}
+              did={did && did}
+              pageVisible={true}
+            ></Graphs>
+          )}
+
+          <Box className={classes.panelContent}>
+            <Box
+              className={classes.cardHeader}
+              title={gettext('Server activity')}
+            >
+              {gettext('Server activity')}{' '}
+            </Box>
+            <Tabs
+              value={val}
+              onChange={tabChanged}
+              className={classes.searchInput}
+            >
+              {tab.map((tabValue, i) => {
+                return <Tab key={i} label={tabValue} title={tabValue}/>;
+              })}
+            </Tabs>
+
+            <PgTable
+              columns={
+                val === 0
+                  ? activityColumns
+                  : val === 1
+                    ? databaseLocksColumns
+                    : val == 2
+                      ? databasePreparedColumns
+                      : serverConfigColumns
+              }
+              data={dashData}
+              schema={schema}
+              panelData={true}
+            ></PgTable>
+          </Box>
+        </Box>
+      ) : sid && !props.serverConnected ? (
+        <div className={classes.emptyPanel}>
+          <div className={classes.panelIcon}>
+            <i className="fa fa-exclamation-circle"></i>
+            <span className={classes.panelMessage}>{gettext(msg)}</span>
+          </div>
+        </div>
+      ) : (
+        <WelcomeDashboard
+          pgBrowser={pgBrowser}
+          node={node}
+          itemData={nodeData}
+          item={item}
+          sid={sid}
+          did={did}
+        />
+      )}
+    </>
+  );
+}
+
+Dashboard.propTypes = {
+  node: PropTypes.func,
+  itemData: PropTypes.object,
+  nodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  item: PropTypes.object,
+  pgBrowser: PropTypes.object,
+  preferences: PropTypes.object,
+  sid: PropTypes.string,
+  did: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
+  row: PropTypes.object,
+  serverConnected: PropTypes.bool,
+};
+
+export function ChartContainer(props) {
+  return (
+    <div
+      className="card dashboard-graph"
+      role="object-document"
+      tabIndex="0"
+      aria-labelledby={props.id}
+    >
+      <div className="card-header">
+        <div className="d-flex">
+          <div id={props.id}>{props.title}</div>
+          <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
+        </div>
+      </div>
+      <div className="card-body dashboard-graph-body">
+        <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none' : '')}>
+          {props.children}
+        </div>
+        <ChartError message={props.errorMsg} />
+      </div>
+    </div>
+  );
+}
+
+ChartContainer.propTypes = {
+  id: PropTypes.string.isRequired,
+  title: PropTypes.string.isRequired,
+  legendRef: PropTypes.oneOfType([
+    PropTypes.func,
+    PropTypes.shape({ current: PropTypes.any }),
+  ]).isRequired,
+  children: PropTypes.node.isRequired,
+  errorMsg: PropTypes.string,
+};
+
+export function ChartError(props) {
+  if (props.message === null) {
+    return <></>;
+  }
+  return (
+    <div className="pg-panel-error pg-panel-message" role="alert">
+      {props.message}
+    </div>
+  );
+}
+
+ChartError.propTypes = {
+  message: PropTypes.string,
+};
+
+export function DashboardRow({ children }) {
+  return <div className="row dashboard-row">{children}</div>;
+}
+DashboardRow.propTypes = {
+  children: PropTypes.node.isRequired,
+};
+
+export function DashboardRowCol({ breakpoint, parts, children }) {
+  return <div className={`col-${breakpoint}-${parts}`}>{children}</div>;
+}
+
+DashboardRowCol.propTypes = {
+  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
+  parts: PropTypes.number.isRequired,
+  children: PropTypes.node.isRequired,
+};
diff --git a/web/pgadmin/dashboard/static/js/Graphs.jsx b/web/pgadmin/dashboard/static/js/Graphs.jsx
index cd8fa65a3..69a9af4fc 100644
--- a/web/pgadmin/dashboard/static/js/Graphs.jsx
+++ b/web/pgadmin/dashboard/static/js/Graphs.jsx
@@ -8,7 +8,7 @@
 //////////////////////////////////////////////////////////////
 import React, { useEffect, useRef, useState, useReducer, useCallback, useMemo } from 'react';
 import {LineChart} from 'sources/chartjs';
-import {ChartContainer, DashboardRowCol, DashboardRow} from './dashboard_components';
+import {ChartContainer, DashboardRowCol, DashboardRow} from './Dashboard';
 import url_for from 'sources/url_for';
 import axios from 'axios';
 import gettext from 'sources/gettext';
diff --git a/web/pgadmin/dashboard/static/js/PgAdminLogo.jsx b/web/pgadmin/dashboard/static/js/PgAdminLogo.jsx
new file mode 100644
index 000000000..b2f7425db
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/PgAdminLogo.jsx
@@ -0,0 +1,219 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+
+export default function PgAdminLogo() {
+
+  return (
+    <div className="welcome-logo" aria-hidden="true">
+      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 130">
+        <defs>
+          <style>{'.cls-1{stroke:#000;stroke-width:10.19px;}.cls-2{fill:#336791;}.cls-3,.cls-4,.cls-9{fill:none;}.cls-3,.cls-4,.cls-5,.cls-6{stroke:#fff;}.cls-3,.cls-4{stroke-linecap:round;stroke-width:3.4px;}.cls-3{stroke-linejoin:round;}.cls-4{stroke-linejoin:bevel;}.cls-5,.cls-6{fill:#fff;}.cls-5{stroke-width:1.13px;}.cls-6{stroke-width:0.57px;}.cls-7{fill:#2775b6;}.cls-8{fill:#333;}.cls-9{stroke:#333;stroke-width:3px;}'}</style>
+        </defs>
+        <title>pgAdmin_PostgreSQL</title>
+        <g id="Layer_1" data-name="Layer 1">
+          <g id="Layer_3">
+            <path
+              className="cls-1"
+              d="M95.59,93.65c.77-6.44.54-7.38,5.33-6.34l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21a9,9,0,0,0,.1,2.46c-3.7,4.13-2.62,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.46,1.16,1.36,8.35,1.56,13.48s.55,9.93,1.6,12.75,2.28,10.1,12,8C88.81,119.46,95,117,95.59,93.65"
+            />
+            <path
+              className="cls-2"
+              d="M117.17,79.2c-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21A9.41,9.41,0,0,0,59,80.22c-3.7,4.13-2.61,4.86-10,6.38s-3.08,4.29-.21,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.45,1.16,2.47,7.56,2.3,13.35s-.28,9.77.86,12.88,2.28,10.1,12,8C88.81,119.46,93,115,93.6,107.42,94,102.07,95,102.87,95,98.08l.75-2.26c.87-7.26.14-9.6,5.15-8.51l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31Z"
+            />
+            <path
+              className="cls-3"
+              d="M66.33,83.36c-.38,13.5.09,27.09,1.41,30.39s4.15,9.73,13.88,7.64c8.12-1.74,11.08-5.11,12.36-12.55.94-5.47,2.77-20.67,3-23.79"
+            />
+            <path
+              className="cls-3"
+              d="M54.67,15.7s-44-18-42,22.93c.44,8.7,12.48,65.87,26.84,48.6,5.25-6.32,10-11.27,10-11.27"
+            />
+            <path
+              className="cls-3"
+              d="M78.45,12.42c-1.52.47,24.49-9.51,39.28,9.38,5.22,6.67-.83,33.94-15.31,55.42"
+            />
+            <path
+              className="cls-4"
+              d="M102.42,77.22s.94,4.64,14.65,1.81c6-1.24,2.4,3.48-3.7,6.31-5,2.32-16.21,2.92-16.39-.29-.47-8.27,5.9-5.76,5.44-7.83-.42-1.87-3.26-3.7-5.15-8.27-1.64-4-22.57-34.58,5.8-30,1-.22-7.4-27-33.95-27.42S43.45,44.14,43.45,44.14"
+            />
+            <path
+              className="cls-3"
+              d="M58.9,80.05c-3.7,4.13-2.61,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52,1.66-2.32,0-6-2.28-7-1.1-.46-2.57-1-4.46,1.09Z"
+            />
+            <path
+              className="cls-3"
+              d="M58.66,80c-.38-2.44.79-5.33,2.05-8.71C62.6,66.19,67,61.11,63.47,45c-2.6-12-20-2.5-20-.87a81.48,81.48,0,0,1-.29,16c-1.41,10.06,6.4,18.57,15.39,17.7"
+            />
+            <path
+              className="cls-5"
+              d="M54.51,43.9c-.08.55,1,2,2.45,2.23a2.62,2.62,0,0,0,2.72-1.51c.08-.56-1-1.17-2.44-1.37s-2.65.09-2.73.65Z"
+            />
+            <path
+              className="cls-6"
+              d="M98,42.76c.07.56-1,2-2.45,2.24a2.64,2.64,0,0,1-2.73-1.52c-.07-.55,1-1.16,2.45-1.36s2.65.09,2.73.64Z"
+            />
+            <path
+              className="cls-3"
+              d="M103.07,38.92c.24,4.36-.94,7.33-1.08,12-.22,6.74,3.21,14.46-2,22.19"
+            />
+          </g>
+          <path
+            className="cls-7 app-name"
+            d="M154.72,28.15h5.16v4.16A12.84,12.84,0,0,1,163.35,29a11.17,11.17,0,0,1,6.28-1.76,11.84,11.84,0,0,1,9.08,4.09c2.48,2.72,3.73,6.62,3.73,11.67q0,10.26-5.38,14.65a12.2,12.2,0,0,1-7.95,2.79,10.78,10.78,0,0,1-6-1.56,13.55,13.55,0,0,1-3.14-3v16h-5.28Zm19.84,24.6Q177,49.65,177,43.5a17,17,0,0,0-1.09-6.44,7.51,7.51,0,0,0-7.53-5.19q-5.49,0-7.52,5.48a21.49,21.49,0,0,0-1.09,7.44A15.64,15.64,0,0,0,160.88,51a8,8,0,0,0,13.68,1.78Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M206,29.26a14.6,14.6,0,0,1,3,3V28.3h4.86V56.83c0,4-.58,7.13-1.75,9.44q-3.27,6.38-12.35,6.38a15.07,15.07,0,0,1-8.5-2.27,8.86,8.86,0,0,1-3.85-7.1h5.36a6,6,0,0,0,1.52,3.25q1.77,1.75,5.59,1.76,6,0,7.9-4.28,1.1-2.52,1-9a10.39,10.39,0,0,1-3.8,3.57,13.56,13.56,0,0,1-14.75-2.45q-3.81-3.62-3.81-12,0-7.89,3.84-12.31a11.85,11.85,0,0,1,9.27-4.42A11.37,11.37,0,0,1,206,29.26Zm.64,5.66a7.61,7.61,0,0,0-6.09-2.81A7.52,7.52,0,0,0,193,37.32a20.56,20.56,0,0,0-1.08,7.3c0,3.53.72,6.22,2.14,8.07a6.93,6.93,0,0,0,5.76,2.77,8.09,8.09,0,0,0,8-5.13A16.72,16.72,0,0,0,209,43.56Q209,37.73,206.62,34.92Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M235.16,16.34h6.58l15.62,43H251l-4.5-12.89H229.6l-4.67,12.89h-6Zm9.67,25.4-6.63-19-6.88,19Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M279.16,29a14.3,14.3,0,0,1,3.18,3.08V16.2h5.07V59.38h-4.75V55a11.33,11.33,0,0,1-4.35,4.19,12.51,12.51,0,0,1-5.75,1.28,11.61,11.61,0,0,1-9-4.4q-3.82-4.41-3.83-11.74a20.35,20.35,0,0,1,3.49-11.88,11.41,11.41,0,0,1,10-5A11.15,11.15,0,0,1,279.16,29ZM267.39,52.5q2.13,3.39,6.82,3.39a7.17,7.17,0,0,0,6-3.14c1.56-2.1,2.35-5.12,2.35-9s-.81-6.9-2.42-8.81a7.56,7.56,0,0,0-6-2.85,7.88,7.88,0,0,0-6.43,3c-1.64,2-2.46,5-2.46,9A15.62,15.62,0,0,0,267.39,52.5Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M295.29,28h5.21v4.46a17.4,17.4,0,0,1,3.4-3.37,10.24,10.24,0,0,1,5.92-1.79,9.34,9.34,0,0,1,6,1.85,9.61,9.61,0,0,1,2.34,3.1,11.37,11.37,0,0,1,4.13-3.73,11.52,11.52,0,0,1,5.33-1.22q6.33,0,8.62,4.57a15,15,0,0,1,1.23,6.62V59.38H332V37.58c0-2.09-.52-3.52-1.57-4.3a6.2,6.2,0,0,0-3.82-1.17,7.58,7.58,0,0,0-5.35,2.08c-1.49,1.38-2.24,3.7-2.24,6.94V59.38h-5.36V38.9a10.78,10.78,0,0,0-.76-4.66q-1.2-2.19-4.49-2.19A7.73,7.73,0,0,0,303,34.36c-1.63,1.54-2.45,4.34-2.45,8.38V59.38h-5.27Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M345.27,16.34h5.36v6h-5.36Zm0,11.81h5.36V59.38h-5.36Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M358.6,28h5v4.46a14,14,0,0,1,4.72-4,12.56,12.56,0,0,1,5.53-1.2c4.46,0,7.46,1.55,9,4.66a16.52,16.52,0,0,1,1.29,7.29V59.38h-5.37V39.61A10.8,10.8,0,0,0,378,35a5.15,5.15,0,0,0-5.1-2.93,10.21,10.21,0,0,0-3.08.38A8,8,0,0,0,366,35a7.66,7.66,0,0,0-1.71,3.2,21.84,21.84,0,0,0-.4,4.74V59.38H358.6Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M155.24,86.87h3.9l5.77,17,5.74-17h3.87V107h-2.6V95.1q0-.61,0-2c0-.94,0-2,0-3L166.24,107h-2.7L157.75,90v.61c0,.49,0,1.24,0,2.25s.05,1.75.05,2.22V107h-2.6Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M186.15,98.09a1.35,1.35,0,0,0,1.14-.71,2.31,2.31,0,0,0,.16-.94,2,2,0,0,0-.89-1.84A4.79,4.79,0,0,0,184,94a3.21,3.21,0,0,0-2.73,1,3.44,3.44,0,0,0-.59,1.72h-2.3A4.28,4.28,0,0,1,180.14,93,7.16,7.16,0,0,1,184.05,92a8,8,0,0,1,4.19,1,3.34,3.34,0,0,1,1.6,3.06v8.44a1.06,1.06,0,0,0,.16.62.77.77,0,0,0,.66.23l.37,0,.44-.07V107a7.38,7.38,0,0,1-.88.21,5.92,5.92,0,0,1-.82,0,2,2,0,0,1-1.84-.9,3.63,3.63,0,0,1-.43-1.36,6.16,6.16,0,0,1-2.16,1.71,6.56,6.56,0,0,1-3.1.73,4.59,4.59,0,0,1-3.33-1.24,4.09,4.09,0,0,1-1.29-3.09,4,4,0,0,1,1.27-3.16,6.16,6.16,0,0,1,3.34-1.38ZM181,104.74a2.88,2.88,0,0,0,1.84.62,5.51,5.51,0,0,0,2.52-.61,3.37,3.37,0,0,0,2-3.26v-2a3.79,3.79,0,0,1-1.16.48,10.37,10.37,0,0,1-1.39.28l-1.49.19a5.68,5.68,0,0,0-2,.56,2.18,2.18,0,0,0-1.14,2A2,2,0,0,0,181,104.74Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M193.88,92.31h2.33v2.08a6.73,6.73,0,0,1,2.2-1.85A6,6,0,0,1,201,92q3.12,0,4.21,2.18a7.73,7.73,0,0,1,.6,3.4V107h-2.5V97.73a4.87,4.87,0,0,0-.4-2.16,2.41,2.41,0,0,0-2.38-1.37,4.75,4.75,0,0,0-1.43.18,3.68,3.68,0,0,0-1.78,1.2,3.55,3.55,0,0,0-.8,1.5,10.3,10.3,0,0,0-.18,2.21V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M217.29,98.09a1.33,1.33,0,0,0,1.14-.71,2.15,2.15,0,0,0,.16-.94,2,2,0,0,0-.89-1.84,4.79,4.79,0,0,0-2.56-.56,3.24,3.24,0,0,0-2.73,1,3.44,3.44,0,0,0-.58,1.72h-2.3A4.27,4.27,0,0,1,211.28,93,7.19,7.19,0,0,1,215.2,92a8,8,0,0,1,4.19,1A3.36,3.36,0,0,1,221,96v8.44a1.14,1.14,0,0,0,.15.62.79.79,0,0,0,.67.23l.37,0,.43-.07V107a7.32,7.32,0,0,1-.87.21,6,6,0,0,1-.82,0,2,2,0,0,1-1.85-.9,3.46,3.46,0,0,1-.42-1.36,6.16,6.16,0,0,1-2.16,1.71,6.63,6.63,0,0,1-3.11.73,4.58,4.58,0,0,1-3.32-1.24,4.06,4.06,0,0,1-1.3-3.09A4,4,0,0,1,210,100a6.13,6.13,0,0,1,3.33-1.38Zm-5.18,6.65a2.91,2.91,0,0,0,1.85.62,5.47,5.47,0,0,0,2.51-.61,3.38,3.38,0,0,0,2.06-3.26v-2a3.9,3.9,0,0,1-1.16.48,10.51,10.51,0,0,1-1.4.28l-1.48.19a5.55,5.55,0,0,0-2,.56,2.17,2.17,0,0,0-1.15,2A2,2,0,0,0,212.11,104.74Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M233.16,92.9a7.05,7.05,0,0,1,1.42,1.39V92.45h2.27v13.32a10,10,0,0,1-.82,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.15,4.15,0,0,1-1.8-3.32H227a2.81,2.81,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.88,0,3.1-.66,3.68-2a11.15,11.15,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,5.93,5.93,0,0,1-2.74.54,5.79,5.79,0,0,1-4.14-1.69q-1.79-1.68-1.78-5.58a8.49,8.49,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.33,5.33,0,0,1,233.16,92.9Zm.3,2.64a3.77,3.77,0,0,0-6.38,1.12,9.73,9.73,0,0,0-.5,3.4,6.05,6.05,0,0,0,1,3.77,3.21,3.21,0,0,0,2.68,1.29,3.77,3.77,0,0,0,3.72-2.39,7.71,7.71,0,0,0,.6-3.16A6.13,6.13,0,0,0,233.46,95.54Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M249.64,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,17.44,17.44,0,0,1,.22,3.23H242.4a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3.05-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.58,6.58,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.71,8.71,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,249.64,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M256.16,92.31h2.44v2.08a8.23,8.23,0,0,1,1.58-1.57A4.79,4.79,0,0,1,263,92a4.31,4.31,0,0,1,2.81.87,4.5,4.5,0,0,1,1.1,1.44,5.27,5.27,0,0,1,1.92-1.74,5.37,5.37,0,0,1,2.49-.57,4.08,4.08,0,0,1,4,2.14,7,7,0,0,1,.58,3.09V107h-2.56V96.78a2.41,2.41,0,0,0-.73-2,2.93,2.93,0,0,0-1.79-.54,3.53,3.53,0,0,0-2.49,1,4.23,4.23,0,0,0-1.05,3.24V107h-2.5V97.4a5,5,0,0,0-.36-2.18,2.17,2.17,0,0,0-2.09-1,3.59,3.59,0,0,0-2.53,1.08c-.76.72-1.14,2-1.14,3.91V107h-2.47Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M288.53,92.72a5.47,5.47,0,0,1,2.22,1.89,6.67,6.67,0,0,1,1,2.58,17.66,17.66,0,0,1,.21,3.23H281.29a6.42,6.42,0,0,0,1,3.59,3.48,3.48,0,0,0,3,1.35,3.9,3.9,0,0,0,3.06-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5.23,5.23,0,0,1-.64,1.8,6.56,6.56,0,0,1-1.2,1.62,5.7,5.7,0,0,1-2.76,1.48,8.62,8.62,0,0,1-2,.21,6.14,6.14,0,0,1-4.61-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.91-5.72,6.24,6.24,0,0,1,5-2.21A6.58,6.58,0,0,1,288.53,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.53,3.53,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.63,4.63,0,0,0-1.2,3.11Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M295.06,92.31h2.34v2.08a6.63,6.63,0,0,1,2.2-1.85,5.91,5.91,0,0,1,2.58-.56c2.08,0,3.49.73,4.21,2.18a7.57,7.57,0,0,1,.61,3.4V107h-2.51V97.73a5,5,0,0,0-.39-2.16,2.41,2.41,0,0,0-2.38-1.37,4.86,4.86,0,0,0-1.44.18,3.7,3.7,0,0,0-1.77,1.2,3.55,3.55,0,0,0-.8,1.5,9.58,9.58,0,0,0-.19,2.21V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M311.13,88.22h2.48v4.09H316v2h-2.34v9.56a1,1,0,0,0,.52,1,2.21,2.21,0,0,0,1,.15h.38l.48,0v2a4.16,4.16,0,0,1-.88.18,7.74,7.74,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88,3.94,3.94,0,0,1-.61-2.29v-9.7h-2v-2h2Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M340.63,86.87v2.39h-6.77V107h-2.75V89.26h-6.76V86.87Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M350.31,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2A8.08,8.08,0,0,1,338.7,100a8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.6,6.6,0,0,1,350.31,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.49,3.49,0,0,0-3.25,1.72,8.07,8.07,0,0,0-1,4.15,7.05,7.05,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.35,3.35,0,0,0,348.78,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M365.88,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2,8.08,8.08,0,0,1-1.77-5.48,8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,365.88,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.46,3.46,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.54,3.54,0,0,0,3.21,1.56A3.35,3.35,0,0,0,364.35,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M370.91,86.87h2.46V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M378.53,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.86,4.86,0,0,0,2.45-.6A2,2,0,0,0,386,103a1.56,1.56,0,0,0-.84-1.43,10.63,10.63,0,0,0-2.14-.7l-2-.49a10,10,0,0,1-2.81-1,3.11,3.11,0,0,1-1.61-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.83,1.94a4.24,4.24,0,0,1,.91,2.65h-2.33A2.72,2.72,0,0,0,385,95a3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.65,1.65,0,0,0-.74,1.4,1.73,1.73,0,0,0,1,1.53,5.69,5.69,0,0,0,1.64.6l1.66.4A12.73,12.73,0,0,1,387,99.75a3.3,3.3,0,0,1,1.44,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43c-2.2,0-3.77-.5-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M400,87.84c.58-.84,1.68-1.26,3.32-1.26l.48,0,.56,0v2.24l-.56,0h-.32c-.76,0-1.21.19-1.36.58a11.75,11.75,0,0,0-.22,3h2.46v1.94h-2.46V107h-2.43V94.32h-2V92.38h2v-2.3A4.43,4.43,0,0,1,400,87.84Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M417.23,93.77a7.38,7.38,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.18,6.18,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2,8.07,8.07,0,0,1-1.76-5.48,8.83,8.83,0,0,1,1.85-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,417.23,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.47,3.47,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.55,3.55,0,0,0,3.22,1.56A3.35,3.35,0,0,0,415.7,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M422.26,92.31h2.34v2.53A5.61,5.61,0,0,1,426,93,3.68,3.68,0,0,1,428.59,92l.24,0,.56,0v2.6a2.08,2.08,0,0,0-.41-.05l-.4,0a3.52,3.52,0,0,0-2.86,1.2,4.2,4.2,0,0,0-1,2.75V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M439.89,86.87h9a6.09,6.09,0,0,1,4.31,1.51,5.5,5.5,0,0,1,1.64,4.25,6.15,6.15,0,0,1-1.47,4.09,5.5,5.5,0,0,1-4.47,1.74h-6.27V107h-2.72Zm10.55,2.76a5.92,5.92,0,0,0-2.46-.42h-5.37v7H448a5.07,5.07,0,0,0,2.95-.78,3.1,3.1,0,0,0,1.14-2.75A3,3,0,0,0,450.44,89.63Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M468.58,93.77a7.38,7.38,0,0,1,1.95,5.55,9.51,9.51,0,0,1-1.72,5.85,6.17,6.17,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2A8.07,8.07,0,0,1,457,100a8.78,8.78,0,0,1,1.86-5.88,6.23,6.23,0,0,1,5-2.18A6.56,6.56,0,0,1,468.58,93.77Zm-1.52,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.65,3.65,0,0,0-3.55-2,3.48,3.48,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.36,3.36,0,0,0,467.06,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M475,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.93,4.93,0,0,0,2.46-.6,2,2,0,0,0,1.06-1.84,1.55,1.55,0,0,0-.85-1.43,10.4,10.4,0,0,0-2.14-.7l-2-.49a9.78,9.78,0,0,1-2.8-1,3.1,3.1,0,0,1-1.62-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.84,1.94a4.17,4.17,0,0,1,.9,2.65h-2.33a2.72,2.72,0,0,0-.6-1.51,3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.64,1.64,0,0,0-.73,1.4,1.72,1.72,0,0,0,1,1.53,5.66,5.66,0,0,0,1.65.6l1.65.4a12.83,12.83,0,0,1,3.63,1.24,3.31,3.31,0,0,1,1.43,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43q-3.3,0-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M488,88.22h2.49v4.09h2.34v2h-2.34v9.56a1,1,0,0,0,.52,1,2.19,2.19,0,0,0,.95.15h.39l.48,0v2a4.39,4.39,0,0,1-.89.18,7.52,7.52,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88A3.94,3.94,0,0,1,488,104v-9.7h-2v-2h2Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M503.47,92.9a6.78,6.78,0,0,1,1.41,1.39V92.45h2.27v13.32a10,10,0,0,1-.81,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.1,4.1,0,0,1-1.8-3.32h2.5a2.74,2.74,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.87,0,3.1-.66,3.68-2a11.37,11.37,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,6,6,0,0,1-2.74.54,5.83,5.83,0,0,1-4.15-1.69q-1.77-1.68-1.77-5.58a8.43,8.43,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.38,5.38,0,0,1,503.47,92.9Zm.3,2.64a3.56,3.56,0,0,0-2.85-1.31,3.5,3.5,0,0,0-3.53,2.43,9.48,9.48,0,0,0-.51,3.4,6.12,6.12,0,0,0,1,3.77,3.24,3.24,0,0,0,2.69,1.29,3.75,3.75,0,0,0,3.71-2.39,7.71,7.71,0,0,0,.6-3.16A6.14,6.14,0,0,0,503.77,95.54Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M511,92.31h2.33v2.53a5.91,5.91,0,0,1,1.41-1.8A3.69,3.69,0,0,1,517.3,92l.23,0,.56,0v2.6a2.08,2.08,0,0,0-.4-.05l-.41,0a3.48,3.48,0,0,0-2.85,1.2,4.14,4.14,0,0,0-1,2.75V107H511Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M529.27,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,16.6,16.6,0,0,1,.22,3.23H522a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3-1.28,4.37,4.37,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.34,6.34,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.65,8.65,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,529.27,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M537.9,100.47a5.6,5.6,0,0,0,.78,2.78q1.3,2,4.59,2a7.9,7.9,0,0,0,2.69-.44,3.09,3.09,0,0,0,2.34-3,2.64,2.64,0,0,0-1-2.33,9.55,9.55,0,0,0-3.15-1.19l-2.64-.62a11.41,11.41,0,0,1-3.65-1.33A4.23,4.23,0,0,1,536,92.54a5.86,5.86,0,0,1,1.83-4.44A7.16,7.16,0,0,1,543,86.37a8.75,8.75,0,0,1,5.22,1.52,5.57,5.57,0,0,1,2.15,4.87h-2.56a5.12,5.12,0,0,0-.84-2.47c-.79-1.05-2.14-1.57-4.05-1.57a4.51,4.51,0,0,0-3.31,1,3.2,3.2,0,0,0-1,2.35,2.33,2.33,0,0,0,1.19,2.16,16.76,16.76,0,0,0,3.54,1.09l2.73.65a8.15,8.15,0,0,1,3,1.27,4.81,4.81,0,0,1,1.86,4.09,5.14,5.14,0,0,1-2.37,4.77,10.46,10.46,0,0,1-5.5,1.43,8.07,8.07,0,0,1-5.72-1.91,6.57,6.57,0,0,1-2-5.16Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M573.17,106.9l-1.36,1.65-3.11-2.36a11.33,11.33,0,0,1-2.43,1,10.29,10.29,0,0,1-2.85.37,9.18,9.18,0,0,1-7.32-3.06A11.71,11.71,0,0,1,553.76,97a11.9,11.9,0,0,1,2-7,8.78,8.78,0,0,1,7.69-3.72c3.54,0,6.17,1.14,7.87,3.42a11.08,11.08,0,0,1,2,6.82,14.28,14.28,0,0,1-.48,3.73,9.67,9.67,0,0,1-2.44,4.46ZM565.35,105a3.36,3.36,0,0,0,1.29-.47l-2.22-1.72,1.37-1.68,2.62,2A7.5,7.5,0,0,0,570.1,100a13.76,13.76,0,0,0,.45-3.39,8.48,8.48,0,0,0-1.85-5.7,6.35,6.35,0,0,0-5.07-2.17,6.6,6.6,0,0,0-5.15,2.08q-1.9,2.07-1.9,6.38A8.64,8.64,0,0,0,558.4,103a6.63,6.63,0,0,0,5.36,2.15A11.24,11.24,0,0,0,565.35,105Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M576.58,86.87h2.72v17.69h10.08V107h-12.8Z"
+          />
+          <line
+            className="cls-9 app-name-underline"
+            x1="219.17"
+            y1="66.5"
+            x2="384.17"
+            y2="66.5"
+          />
+        </g>
+      </svg>
+    </div>);
+
+
+}
\ No newline at end of file
diff --git a/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
new file mode 100644
index 000000000..ebb695dea
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
@@ -0,0 +1,250 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import gettext from 'sources/gettext';
+import _ from 'lodash';
+import { Link, BrowserRouter } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import { makeStyles } from '@material-ui/core/styles';
+import pgAdmin from 'sources/pgadmin';
+import PgAdminLogo from './PgAdminLogo';
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    background: theme.palette.grey[400],
+    overflow: 'hidden',
+    padding: '8px',
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+    height: '100%'
+
+  },
+  dashboardContainer: {
+    paddingTop: '8px',
+    paddingBottom: '8px',
+    minHeight: '100%'
+  },
+  card: {
+    position: 'relative',
+    minWidth: 0,
+    wordWrap: 'break-word',
+    backgroundColor: theme.otherVars.tableBg,
+    backgroundClip: 'border-box',
+    border: '1px solid' + theme.otherVars.borderColor,
+    borderRadius: theme.shape.borderRadius,
+    marginTop: 8
+  },
+  row: {
+    marginRight: '-8px',
+    marginLeft: '-8px'
+  },
+  rowContent: {
+    display: 'flex',
+    flexWrap: 'wrap',
+    marginRight: '-7.5px',
+    marginLeft: '-7.5px'
+  },
+  cardHeader: {
+    padding: '0.25rem 0.5rem',
+    fontWeight: 'bold',
+    backgroundColor: theme.otherVars.tableBg,
+    borderBottom: '1px solid',
+    borderBottomColor: theme.otherVars.borderColor,
+  },
+  dashboardLink: {
+    color: theme.otherVars.colorFg + '!important',
+    flex: '0 0 50%',
+    maxWidth: '50%',
+    textAlign: 'center',
+    cursor: 'pointer'
+  },
+  gettingStartedLink: {
+    flex: '0 0 25%',
+    maxWidth: '50%',
+    textAlign: 'center',
+    cursor: 'pointer'
+  },
+  link: {
+    color: theme.otherVars.colorFg + '!important',
+  },
+  cardColumn: {
+    flex: '0 0 100%',
+    maxWidth: '100%',
+    margin: '8px'
+  },
+  cardBody: {
+    flex: '1 1 auto',
+    minHeight: '1px',
+    padding: '0.5rem !important',
+  }
+}));
+
+
+function AddNewServer(pgBrowser) {
+  if (pgBrowser && pgBrowser.tree) {
+    var i = _.isUndefined(pgBrowser.tree.selected()) ?
+        pgBrowser.tree.first(null, false) :
+        pgBrowser.tree.selected(),
+      serverModule = pgAdmin.Browser.Nodes.server,
+      itemData = pgBrowser.tree.itemData(i);
+
+    while (itemData && itemData._type != 'server_group') {
+      i = pgBrowser.tree.next(i);
+      itemData = pgBrowser.tree.itemData(i);
+    }
+
+    if (!itemData) {
+      return;
+    }
+
+    if (serverModule) {
+      serverModule.callbacks.show_obj_properties.apply(
+        serverModule, [{
+          action: 'create',
+        }, i]
+      );
+    }
+  }
+}
+
+export default function WelcomeDashboard({ pgBrowser }) {
+
+  const classes = useStyles();
+
+  return (
+    <BrowserRouter>
+      <div className={classes.emptyPanel}>
+        <div className={classes.dashboardContainer}>
+          <div className={classes.row}>
+            <div className={classes.cardColumn}>
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Welcome')}</div>
+                <div className={classes.cardBody}>
+                  <PgAdminLogo />
+                  <h4>
+                    {gettext('Feature rich')} | {gettext('Maximises PostgreSQL')}{' '}
+                    | {gettext('Open Source')}{' '}
+                  </h4>
+                  <p>
+                    {gettext(
+                      'pgAdmin is an Open Source administration and management tool for the PostgreSQL database. It includes a graphical administration interface, an SQL query tool, a procedural code debugger and much more. The tool is designed to answer the needs of developers, DBAs and system administrators alike.'
+                    )}
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className={classes.row}>
+            <div className={classes.cardColumn}>
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Quick Links')}</div>
+                <div className={classes.cardBody}>
+                  <div className={classes.rowContent}>
+                    <div className={classes.dashboardLink}>
+                      <Link to="#" onClick={() => { AddNewServer(pgBrowser); }} className={classes.link}>
+                        <span
+                          className="fa fa-4x dashboard-icon fa-server"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Add New Server')}
+                      </Link>
+                    </div>
+                    <div className={classes.dashboardLink}>
+                      <Link to="#" onClick={() => pgAdmin.Preferences.show()} className={classes.link}>
+                        <span
+                          id="mnu_preferences"
+                          className="fa fa-4x dashboard-icon fa-cogs"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Configure pgAdmin')}
+                      </Link>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className={classes.row}>
+            <div className={classes.cardColumn}>
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Getting Started')}</div>
+                <div className={classes.cardBody}>
+                  <div className={classes.rowContent}>
+                    <div className={classes.gettingStartedLink}>
+                      <a
+                        href="http://www.postgresql.org/docs"
+                        target="postgres_help"
+                        className={classes.link}
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon dashboard-pg-doc"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('PostgreSQL Documentation')}
+                      </a>
+                    </div>
+                    <div className={classes.gettingStartedLink}>
+                      <a href="https://www.pgadmin.org" target="pgadmin_website" className={classes.link}>
+                        <span
+                          className="fa fa-4x dashboard-icon fa-globe"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('pgAdmin Website')}
+                      </a>
+                    </div>
+                    <div className={classes.gettingStartedLink}>
+                      <a
+                        href="http://planet.postgresql.org"
+                        target="planet_website"
+                        className={classes.link}
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon fa-book"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Planet PostgreSQL')}
+                      </a>
+                    </div>
+                    <div className={classes.gettingStartedLink}>
+                      <a
+                        href="http://www.postgresql.org/community"
+                        target="postgres_website"
+                        className={classes.link}
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon fa-users"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Community Support')}
+                      </a>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </BrowserRouter>
+  );
+}
+
+
+WelcomeDashboard.propTypes = {
+  pgBrowser: PropTypes.object.isRequired
+};
+
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
deleted file mode 100644
index 258071da4..000000000
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ /dev/null
@@ -1,1209 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import Notify from '../../../static/js/helpers/Notifier';
-
-define('pgadmin.dashboard', [
-  'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
-  'sources/pgadmin', 'backbone', 'backgrid',
-  'pgadmin.alertifyjs', 'pgadmin.backform', 'sources/nodes/dashboard',
-  'sources/window', './ChartsDOM', 'pgadmin.browser', 'bootstrap', 'wcdocker',
-], function(
-  url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid,
-  Alertify, Backform, NodesDashboard, pgWindow, ChartsDOM
-) {
-
-  pgAdmin.Browser = pgAdmin.Browser || {};
-  var pgBrowser = pgAdmin.Browser;
-
-  /* Return back, this has been called more than once */
-  if (pgAdmin.Dashboard)
-    return;
-
-  var dashboardVisible = true,
-    cancel_query_url = '',
-    terminate_session_url = '',
-    is_super_user = false,
-    current_user, maintenance_database,
-    is_server_dashboard = false,
-    is_database_dashboard = false,
-    can_signal_backend = false;
-
-  // Custom BackGrid cell, Responsible for cancelling active sessions
-  var customDashboardActionCell = Backgrid.Extension.DeleteCell.extend({
-    render: function() {
-      this.$el.empty();
-      var self = this,
-        cell_action = self.column.get('cell_action');
-      // if cancel query button then
-      if (cell_action === 'cancel') {
-        this.$el.html(
-          '<i class=\'fa fa-stop\' data-toggle=\'tooltip\' ' +
-          'title=\'' + gettext('Cancel the active query') +
-          '\' aria-label=\''+ gettext('Cancel the active query') +'\'></i>'
-        );
-      } else {
-        this.$el.html(
-          '<i class=\'fa fa-times-circle text-danger\' data-toggle=\'tooltip\' ' +
-          'title=\'' + gettext('Terminate the session') +
-          '\' aria-label=\''+ gettext('Terminate the session') +'\'></i>'
-        );
-      }
-      this.$el.attr('tabindex', 0);
-      this.$el.on('keydown', function(e) {
-        // terminating session or cancel the active query.
-        if (e.keyCode == 32) {
-          self.$el.click();
-        }
-      });
-      this.delegateEvents();
-      return this;
-    },
-    deleteRow: function(e) {
-      var self = this,
-        title, txtConfirm, txtSuccess, txtError, action_url,
-        cell_action = self.column.get('cell_action');
-
-      e.preventDefault();
-
-      var canDeleteRow = Backgrid.callByNeed(
-        self.column.get('canDeleteRow'), self.column, self.model
-      );
-      // If we are not allowed to cancel the query, return from here
-      if (!canDeleteRow)
-        return;
-
-      // This will refresh the grid
-      let refresh_grid = () => {
-        $('#btn_refresh').trigger('click');
-      };
-
-      if (cell_action === 'cancel') {
-        title = gettext('Cancel Active Query?');
-        txtConfirm = gettext('Are you sure you wish to cancel the active query?');
-        txtSuccess = gettext('Active query cancelled successfully.');
-        txtError = gettext('An error occurred whilst cancelling the active query.');
-        action_url = cancel_query_url + self.model.get('pid');
-      } else {
-        title = gettext('Terminate Session?');
-        txtConfirm = gettext('Are you sure you wish to terminate the session?');
-        txtSuccess = gettext('Session terminated successfully.');
-        txtError = gettext('An error occurred whilst terminating the active query.');
-        action_url = terminate_session_url + self.model.get('pid');
-      }
-
-      Notify.confirm(
-        title, txtConfirm,
-        function() {
-          $.ajax({
-            url: action_url,
-            type: 'DELETE',
-          })
-            .done(function(res) {
-              if (res == gettext('Success')) {
-                Notify.success(txtSuccess);
-                refresh_grid();
-              } else {
-                Notify.error(txtError);
-              }
-            })
-            .fail(function(xhr, status, error) {
-              Notify.pgRespErrorNotify(xhr, error);
-            });
-        },
-        function() {
-          return true;
-        }
-      );
-    },
-  });
-
-
-  // Subnode Cell, which will display subnode control
-  var SessionDetailsCell = Backgrid.Extension.ObjectCell.extend({
-    enterEditMode: function() {
-      // Notify that we are about to enter in edit mode for current cell.
-      this.model.trigger('enteringEditMode', [this]);
-
-      Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
-      /* Make sure - we listen to the click event */
-      this.delegateEvents();
-      var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model);
-
-      if (editable) {
-        this.$el.html(
-          '<i class=\'fa fa-caret-down subnode-edit-in-process\'></i>'
-        );
-        this.model.trigger(
-          'pg-sub-node:opened', this.model, this
-        );
-      }
-    },
-    render: function() {
-      this.$el.empty();
-      this.$el.html(
-        '<i class=\'fa fa-caret-right\' data-toggle=\'tooltip\' ' +
-        'title=\'' + gettext('View the active session details') +
-        '\' aria-label=\''+ gettext('View the active session details') +'\'></i>'
-      );
-      this.delegateEvents();
-      if (this.grabFocus)
-        this.$el.trigger('focus');
-      return this;
-    },
-  });
-
-  // Subnode Model
-  var ActiveQueryDetailsModel = Backbone.Model.extend({
-    defaults: {
-      version: null,
-      /* Postgres version */
-    },
-    schema: [{
-      id: 'backend_type',
-      label: gettext('Backend type'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      group: gettext('Details'),
-      visible: function() {
-        return this.version >= 100000;
-      },
-    }, {
-      id: 'query_start',
-      label: gettext('Query started at'),
-      type: 'text',
-      editable: false,
-      readonly: true,
-      group: gettext('Details'),
-    }, {
-      id: 'state_change',
-      label: gettext('Last state changed at'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      group: gettext('Details'),
-    }, {
-      id: 'query',
-      label: gettext('SQL'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      control: Backform.SqlFieldControl,
-      group: gettext('Details'),
-    }],
-  });
-
-  pgAdmin.Dashboard = {
-    init: function() {
-      if (this.initialized)
-        return;
-
-      this.initialized = true;
-      this.chartsDomObj = null;
-
-      this.sid = this.did = -1;
-      this.version = -1;
-
-
-      // Bind the Dashboard object with the 'object_selected' function
-      var selected = this.object_selected.bind(this);
-      var disconnected = this.object_disconnected.bind(this);
-
-      // Listen for selection of any of object
-      pgBrowser.Events.on('pgadmin-browser:tree:selected', selected);
-
-      // Listen for server disconnected event
-      pgBrowser.Events.on('pgadmin:server:disconnect', disconnected);
-
-      // Load the default welcome dashboard
-      var url = url_for('dashboard.index');
-
-      var dashboardPanel = pgBrowser.panels['dashboard'].panel;
-      if (dashboardPanel) {
-        var div = dashboardPanel.layout().scene().find('.pg-panel-content');
-        if (div) {
-          var ajaxHook = function() {
-            $.ajax({
-              url: url,
-              type: 'GET',
-              dataType: 'html',
-            })
-              .done(function(data) {
-                $(div).html(data);
-              })
-              .fail(function(xhr, error) {
-                self.onFail(xhr, error, div, ajaxHook);
-              });
-          };
-          $(div).html(
-            '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
-          );
-          ajaxHook();
-
-          // Cache the current IDs for next time
-          $(dashboardPanel).data('sid', -1);
-          $(dashboardPanel).data('did', -1);
-        }
-      }
-    },
-
-    onFail: function(xhr, error, div, ajaxHook) {
-      Notify.pgNotifier(
-        error, xhr,
-        gettext('An error occurred whilst loading the dashboard.'),
-        function(msg) {
-          if(msg === 'CRYPTKEY_SET') {
-            ajaxHook();
-          } else {
-            $(div).html(
-              '<div class="pg-panel-message" role="alert">' + gettext('An error occurred whilst loading the dashboard.') + '</div>'
-            );
-          }
-        }
-      );
-    },
-
-    // Handle Server Disconnect
-    object_disconnected: function() {
-      let item = pgBrowser.tree.selected(),
-        itemData = item && pgBrowser.tree.itemData(item);
-
-      // The server connected may not be the same one, which was selected, and
-      // we do care out the current selected one only.
-      if (item.length != 0) {
-        this.object_selected(item, itemData);
-      }
-    },
-
-    // Handle treeview clicks
-    object_selected: function(item, itemData) {
-      let self = this;
-
-      if (itemData && itemData._type) {
-        var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
-          url = NodesDashboard.url(itemData, item, treeHierarchy);
-
-        if (url === null) {
-          url = url_for('dashboard.index');
-          self.version = (treeHierarchy.server && treeHierarchy.server.version) || 0;
-
-          cancel_query_url = url + 'cancel_query/';
-          terminate_session_url = url + 'terminate_session/';
-
-          // Check if user is super user
-          var server = treeHierarchy['server'];
-          maintenance_database = (server && server.db) || null;
-          can_signal_backend = (server && server.user) ? server.user.can_signal_backend : false;
-
-          if (server && server.user && server.user.is_superuser) {
-            is_super_user = true;
-          } else {
-            is_super_user = false;
-            // Set current user
-            current_user = (server && server.user) ? server.user.name : null;
-          }
-
-          if ('database' in treeHierarchy) {
-            self.sid = treeHierarchy.server._id;
-            self.did = treeHierarchy.database._id;
-            is_server_dashboard = false;
-            is_database_dashboard = true;
-            url += self.sid + '/' + self.did;
-            cancel_query_url += self.sid + '/' + self.did + '/';
-            terminate_session_url += self.sid + '/' + self.did + '/';
-          } else if ('server' in treeHierarchy) {
-            self.sid = treeHierarchy.server._id;
-            self.did = -1;
-            is_server_dashboard = true;
-            is_database_dashboard = false;
-            url += self.sid;
-            cancel_query_url += self.sid + '/';
-            terminate_session_url += self.sid + '/';
-          } else {
-            is_server_dashboard = is_database_dashboard = false;
-          }
-        } else {
-          is_server_dashboard = is_database_dashboard = false;
-        }
-
-        var dashboardPanel = pgBrowser.panels['dashboard'].panel;
-        if (dashboardPanel) {
-          var div = dashboardPanel.layout().scene().find(
-            '.pg-panel-content'
-          );
-
-          if (div) {
-            if (itemData.connected || _.isUndefined(itemData.connected)) {
-              // Avoid unnecessary reloads
-              if (
-                url !== $(dashboardPanel).data('dashboard_url') || (
-                  url === $(dashboardPanel).data('dashboard_url') &&
-                  $(dashboardPanel).data('server_status') == false
-                )
-              ) {
-                this.chartsDomObj && this.chartsDomObj.unmount();
-                $(div).empty();
-
-                let ajaxHook = function() {
-                  $.ajax({
-                    url: url,
-                    type: 'GET',
-                    dataType: 'html',
-                  })
-                    .done(function(data) {
-                      $(div).html(data);
-                      self.init_dashboard();
-                    })
-                    .fail(function(xhr, error) {
-                      self.onFail(xhr, error, div, ajaxHook);
-                    });
-                };
-                $(div).html(
-                  '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
-                );
-                ajaxHook();
-                $(dashboardPanel).data('server_status', true);
-              }
-            } else {
-              this.chartsDomObj && this.chartsDomObj.unmount();
-              $(div).html(
-                '<div class="pg-panel-message" role="alert">' + gettext('Please connect to the selected server to view the dashboard.') + '</div>'
-              );
-              $(dashboardPanel).data('server_status', false);
-            }
-            // Cache the current IDs for next time
-            $(dashboardPanel).data('dashboard_url', url);
-          }
-        }
-      }
-    },
-
-    // Handler function to support the "Add Server" link
-    add_new_server: function() {
-      if (pgBrowser && pgBrowser.tree) {
-        var i = _.isUndefined(pgBrowser.tree.selected()) ?
-            pgBrowser.tree.first(null, false):
-            pgBrowser.tree.selected(),
-          serverModule = require('pgadmin.node.server'),
-          itemData = pgBrowser.tree.itemData(i);
-
-        while (itemData && itemData._type != 'server_group') {
-          i = pgBrowser.tree.next(i);
-          itemData = pgBrowser.tree.itemData(i);
-        }
-
-        if (!itemData) {
-          return;
-        }
-
-        if (serverModule) {
-          serverModule.callbacks.show_obj_properties.apply(
-            serverModule, [{
-              action: 'create',
-            }, i]
-          );
-        }
-      }
-    },
-
-    // Render a grid
-    render_grid: function(container, url, columns) {
-      var Datum = Backbone.Model.extend({}),
-        self = this;
-
-      var path = url + self.sid;
-      if (self.did != -1) {
-        path += '/' + self.did;
-      }
-
-      var Data = Backbone.Collection.extend({
-        model: Datum,
-        url: path,
-        mode: 'client',
-      });
-
-      var data = new Data();
-
-      var HighlightedRow = Backgrid.Row.extend({
-        render: function() {
-          Backgrid.Row.prototype.render.call(this);
-          var row_type = this.model.get('row_type');
-
-          if (_.isUndefined(row_type) || _.isNull(row_type)) {
-            this.$el.removeClass('alert');
-            this.$el.removeClass('warning');
-          } else if (row_type === 'warning') {
-            this.$el.addClass('warning');
-          } else if (row_type === 'alert') {
-            this.$el.addClass('alert');
-          }
-
-          return this;
-        }
-      });
-
-      // Set up the grid
-      var grid = new Backgrid.Grid({
-        emptyText: gettext('No data found'),
-        columns: columns,
-        collection: data,
-        className: 'backgrid presentation table table-bordered table-noouter-border table-hover',
-        row: HighlightedRow
-      });
-
-      // Render the grid
-      $(container).empty();
-      $(container).append(grid.render().el);
-
-      // Initialize a client-side filter to filter on the client
-      // mode pageable collection's cache.
-      var filter = new Backgrid.Extension.ClientSideFilter({
-        collection: data,
-      });
-
-      filter.setCustomSearchBox($('#txtGridSearch'));
-      // Stash objects for future use
-      $(container).data('data', data);
-      $(container).data('grid', grid);
-      $(container).data('filter', filter);
-    },
-    __loadMoreRows: function(e) {
-      let elem = e.currentTarget;
-      if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
-        if (this.data.length > 0) {
-          this.local_grid.collection.add(this.data.splice(0, 50));
-        }
-      }
-    },
-    // Render the data in a grid
-    render_grid_data: function(container) {
-      var that = this;
-      var data = $(container).data('data'),
-        grid = $(container).data('grid'),
-        filter = $(container).data('filter');
-
-      if (_.isUndefined(data)) {
-        return null;
-      }
-
-      data.fetch({
-        reset: true,
-        success: function(res) {
-          that.data = res.models;
-          that.local_grid = grid;
-          grid.collection.reset(that.data.splice(0,50));
-
-          // If we're showing an error, remove it, and replace the grid & filter
-          if ($(container).hasClass('grid-error')) {
-            $(container).removeClass('grid-error');
-            $(container).html(grid.render().el);
-            $(filter.el).show();
-          }
-
-          if(that.data.length > 50) {
-            // Listen scroll event to load more rows
-            $('.wcScrollableY').on('scroll', that.__loadMoreRows.bind(that));
-          } else {
-            // Listen scroll event to load more rows
-            $('.wcScrollableY').off('scroll', that.__loadMoreRows);
-          }
-
-          // Re-apply search criteria
-          filter.search();
-        },
-        error: function(model, xhr) {
-          let err = '';
-          let msg = '';
-          let cls = 'info';
-
-          if (xhr.readyState === 0) {
-            msg = gettext('Not connected to the server or the connection to the server has been closed.');
-          } else {
-            err = JSON.parse(xhr.responseText);
-            msg = err.errormsg;
-
-            // If we get a 428, it means the server isn't connected
-            if (xhr.status === 428) {
-              if (_.isUndefined(msg) || _.isNull(msg)) {
-                msg = gettext('Please connect to the selected server to view the table.');
-              }
-            } else {
-              msg = gettext('An error occurred whilst rendering the table.');
-              cls = 'error';
-            }
-          }
-
-          // Replace the content with the error, if not already present. Always update the message
-          if (!$(container).hasClass('grid-error')) {
-            $(filter.el).hide();
-            $(container).addClass('grid-error');
-          }
-
-          $(container).html(
-            '<div class="pg-panel-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
-          );
-
-          // Try again
-          setTimeout(function() {
-            pgAdmin.Dashboard.render_grid_data(container, data);
-          }, 5000);
-        },
-      });
-    },
-
-    // Rock n' roll on the dashboard
-    init_dashboard: function() {
-      let self = this;
-
-      this.chartsDomObj = new ChartsDOM.default(
-        document.getElementById('dashboard-graphs'),
-        self.preferences,
-        self.sid,
-        self.did,
-        $('.dashboard-container')[0].clientHeight <=0 ? false : true
-      );
-
-      /* Cache may take time to load for the first time
-       * Keep trying till available
-       */
-      let cacheIntervalId = setInterval(function() {
-        try {
-          if(pgWindow.default.pgAdmin.Browser.preference_version() > 0) {
-            clearInterval(cacheIntervalId);
-            self.reflectPreferences();
-          }
-        }
-        catch(err) {
-          clearInterval(cacheIntervalId);
-          throw err;
-        }
-      },0);
-
-      /* Register for preference changed event broadcasted */
-      pgBrowser.onPreferencesChange('dashboards', function() {
-        self.reflectPreferences();
-      });
-    },
-
-    reflectPreferences: function() {
-      var self = this;
-      self.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('dashboards');
-      this.chartsDomObj.reflectPreferences(self.preferences);
-
-      if(is_server_dashboard || is_database_dashboard) {
-        if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
-          $('#dashboard-activity').removeClass('dashboard-hidden');
-        }
-        else if(!self.preferences.show_activity) {
-          $('#dashboard-activity').addClass('dashboard-hidden');
-        }
-
-        if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
-          $('#dashboard-activity').removeClass('dashboard-hidden');
-        }
-        else if(!self.preferences.show_activity) {
-          $('#dashboard-activity').addClass('dashboard-hidden');
-        }
-
-        /* Dashboard specific preferences can be updated in the
-         * appropriate functions
-         */
-        if(is_server_dashboard) {
-          self.reflectPreferencesServer();
-        }
-        else if(is_database_dashboard) {
-          self.reflectPreferencesDatabase();
-        }
-      }
-    },
-
-    renderTab: function(e, tab_grid_map) {
-      let prevGrid = tab_grid_map[$(e.relatedTarget).attr('aria-controls')];
-      $(prevGrid).data('filtertext', $('#txtGridSearch').val());
-
-      let currGrid = tab_grid_map[$(e.target).attr('aria-controls')];
-      $('#txtGridSearch').val($(currGrid).data('filtertext'));
-      pgAdmin.Dashboard.render_grid_data(currGrid);
-    },
-
-    reflectPreferencesServer: function() {
-      var self = this;
-      var $dashboardContainer = $('.dashboard-container');
-      var div_server_activity = $dashboardContainer.find('#server_activity').get(0);
-      var div_server_locks = $dashboardContainer.find('#server_locks').get(0);
-      var div_server_prepared = $dashboardContainer.find('#server_prepared').get(0);
-      var div_server_config = $dashboardContainer.find('#server_config').get(0);
-
-      var tab_grid_map = {
-        'tab_server_activity': div_server_activity,
-        'tab_server_locks': div_server_locks,
-        'tab_server_prepared': div_server_prepared,
-        'tab_server_config': div_server_config,
-      };
-
-      // Display server activity
-      if (self.preferences.show_activity) {
-        var server_activity_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'datname',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'usename',
-          label: gettext('User'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'application_name',
-          label: gettext('Application'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'client_addr',
-          label: gettext('Client'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'backend_start',
-          label: gettext('Backend start'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'state',
-          label: gettext('State'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        if (self.version < 90600) {
-          server_activity_columns = server_activity_columns.concat(
-            [{
-              name: 'waiting',
-              label: gettext('Waiting?'),
-              editable: false,
-              cell: 'string',
-            }]);
-        } else {
-          server_activity_columns = server_activity_columns.concat(
-            [{
-              name: 'wait_event',
-              label: gettext('Wait event'),
-              editable: false,
-              cell: 'string',
-            }, {
-              name: 'blocking_pids',
-              label: gettext('Blocking PIDs'),
-              editable: false,
-              cell: 'string',
-            }]);
-        }
-
-        var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
-
-        var subNodeFieldsModel = Backform.generateViewSchema(
-          null, newActiveQueryDetailsModel, 'create', null, null, true
-        );
-
-        // Add version to each field
-        _.each(subNodeFieldsModel[0].fields, function(obj) {
-          obj['version'] = self.version;
-        });
-
-        // Add cancel active query button
-        server_activity_columns.unshift({
-          name: 'pg-backform-expand',
-          label: '',
-          cell: SessionDetailsCell,
-          cell_priority: -1,
-          postgres_version: self.version,
-          schema: subNodeFieldsModel,
-        });
-
-        // Add cancel active query button
-        server_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'cancel',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        server_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'terminate',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        var server_locks_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'datname',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'locktype',
-          label: gettext('Lock type'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'relation',
-          label: gettext('Target relation'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'page',
-          label: gettext('Page'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'tuple',
-          label: gettext('Tuple'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualxid',
-          label: gettext('vXID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transactionid',
-          label: gettext('XID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'classid',
-          label: gettext('Class'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'objid',
-          label: gettext('Object ID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualtransaction',
-          label: gettext('vXID (owner)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'mode',
-          label: gettext('Mode'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'granted',
-          label: gettext('Granted?'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var server_prepared_columns = [{
-          name: 'git',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'database',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'Owner',
-          label: gettext('Owner'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transaction',
-          label: gettext('XID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'prepared',
-          label: gettext('Prepared at'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var server_config_columns = [{
-          name: 'name',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'category',
-          label: gettext('Category'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'setting',
-          label: gettext('Setting'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'unit',
-          label: gettext('Unit'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'short_desc',
-          label: gettext('Description'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        // To align subnode controls properly
-        $(div_server_activity).addClass('pg-el-container');
-        $(div_server_activity).attr('el', 'sm');
-
-        // Render the tabs, but only get data for the activity tab for now
-        pgAdmin.Dashboard.render_grid(
-          div_server_activity, url_for('dashboard.activity'), server_activity_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_locks, url_for('dashboard.locks'), server_locks_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_prepared, url_for('dashboard.prepared'), server_prepared_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_config, url_for('dashboard.config'), server_config_columns
-        );
-
-        pgAdmin.Dashboard.render_grid_data(div_server_activity);
-
-        // (Re)render the appropriate tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
-          self.renderTab(e, tab_grid_map);
-        });
-
-        $('#btn_refresh').off('click').on('click', () => {
-          let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
-          pgAdmin.Dashboard.render_grid_data(currGrid);
-        });
-      }
-    },
-    reflectPreferencesDatabase: function() {
-      var self = this;
-      var div_database_activity = document.getElementById('database_activity');
-      var div_database_locks = document.getElementById('database_locks');
-      var div_database_prepared = document.getElementById('database_prepared');
-
-      var tab_grid_map = {
-        'tab_database_activity': div_database_activity,
-        'tab_database_locks': div_database_locks,
-        'tab_database_prepared': div_database_prepared,
-      };
-
-      // Display server activity
-      if (self.preferences.show_activity) {
-        var database_activity_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'usename',
-          label: gettext('User'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'application_name',
-          label: gettext('Application'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'client_addr',
-          label: gettext('Client'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'backend_start',
-          label: gettext('Backend start'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'state',
-          label: gettext('State'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        if (self.version < 90600) {
-          database_activity_columns = database_activity_columns.concat(
-            [{
-              name: 'waiting',
-              label: gettext('Waiting?'),
-              editable: false,
-              cell: 'string',
-            }]);
-        } else {
-          database_activity_columns = database_activity_columns.concat(
-            [{
-              name: 'wait_event',
-              label: gettext('Wait event'),
-              editable: false,
-              cell: 'string',
-            }, {
-              name: 'blocking_pids',
-              label: gettext('Blocking PIDs'),
-              editable: false,
-              cell: 'string',
-            }]);
-        }
-
-        var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
-
-        var subNodeFieldsModel = Backform.generateViewSchema(
-          null, newActiveQueryDetailsModel, 'create', null, null, true
-        );
-
-        // Add version to each field
-        _.each(subNodeFieldsModel[0].fields, function(obj) {
-          obj['version'] = self.version;
-        });
-
-        // Add cancel active query button
-        database_activity_columns.unshift({
-          name: 'pg-backform-expand',
-          label: '',
-          cell: SessionDetailsCell,
-          cell_priority: -1,
-          postgres_version: self.version,
-          schema: subNodeFieldsModel,
-        });
-
-        database_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'cancel',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-        database_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'terminate',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        var database_locks_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'locktype',
-          label: gettext('Lock type'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'relation',
-          label: gettext('Target relation'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'page',
-          label: gettext('Page'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'tuple',
-          label: gettext('Tuple'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualxid',
-          label: gettext('vXID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transactionid',
-          label: gettext('XID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'classid',
-          label: gettext('Class'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'objid',
-          label: gettext('Object ID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualtransaction',
-          label: gettext('vXID (owner)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'mode',
-          label: gettext('Mode'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'granted',
-          label: gettext('Granted?'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var database_prepared_columns = [{
-          name: 'git',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'Owner',
-          label: gettext('Owner'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transaction',
-          label: gettext('XID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'prepared',
-          label: gettext('Prepared at'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        // To align subnode controls properly
-        $(div_database_activity).addClass('pg-el-container');
-        $(div_database_activity).attr('el', 'sm');
-
-        // Render the tabs, but only get data for the activity tab for now
-        pgAdmin.Dashboard.render_grid(
-          div_database_activity, url_for('dashboard.activity'), database_activity_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_database_locks, url_for('dashboard.locks'), database_locks_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_database_prepared, url_for('dashboard.prepared'), database_prepared_columns
-        );
-
-        pgAdmin.Dashboard.render_grid_data(div_database_activity);
-
-        // (Re)render the appropriate tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
-          self.renderTab(e, tab_grid_map);
-        });
-
-        $('#btn_refresh').off('click').on('click', () => {
-          let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
-          pgAdmin.Dashboard.render_grid_data(currGrid);
-        });
-      }
-    },
-    toggleVisibility: function(visible, closed=false) {
-      dashboardVisible = visible;
-      if(closed) {
-        this.chartsDomObj && this.chartsDomObj.unmount();
-      } else {
-        var t = pgBrowser.tree,
-          i = t ? t.selected() : 0,
-          d = i && t.itemData(i);
-
-        this.chartsDomObj && this.chartsDomObj.setPageVisible(dashboardVisible);
-        this.object_selected(i, d);
-      }
-    },
-    can_take_action: function(m) {
-      // We will validate if user is allowed to cancel the active query
-      // If there is only one active session means it probably our main
-      // connection session
-      var active_sessions = m.collection.where({
-          'state': 'active',
-        }),
-        pg_version = this.get('postgres_version') || null,
-        cell_action = this.get('cell_action') || null,
-        is_cancel_session = cell_action === 'cancel',
-        txtMessage;
-
-      // With PG10, We have background process showing on dashboard
-      // We will not allow user to cancel them as they will fail with error
-      // anyway, so better usability we will throw our on notification
-
-      // Background processes do not have database field populated
-      if (pg_version && pg_version >= 100000 && !m.get('datname')) {
-        if (is_cancel_session) {
-          txtMessage = gettext('You cannot cancel background worker processes.');
-        } else {
-          txtMessage = gettext('You cannot terminate background worker processes.');
-        }
-        Notify.info(txtMessage);
-        return false;
-        // If it is the last active connection on maintenance db then error out
-      } else if (maintenance_database == m.get('datname') &&
-        m.get('state') == 'active' && active_sessions.length == 1) {
-        if (is_cancel_session) {
-          txtMessage = gettext('You are not allowed to cancel the main active session.');
-        } else {
-          txtMessage = gettext('You are not allowed to terminate the main active session.');
-        }
-        Notify.error(txtMessage);
-        return false;
-      } else if (is_cancel_session && m.get('state') == 'idle') {
-        // If this session is already idle then do nothing
-        Notify.info(
-          gettext('The session is already in idle state.')
-        );
-        return false;
-      } else if (can_signal_backend) {
-        // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
-        return true;
-      } else if (is_super_user) {
-        // Super user can do anything
-        return true;
-      } else if (current_user && current_user == m.get('usename')) {
-        // Non-super user can cancel only their active queries
-        return true;
-      } else {
-        // Do not allow to cancel someone else session to non-super user
-        if (is_cancel_session) {
-          txtMessage = gettext('Superuser privileges are required to cancel another users query.');
-        } else {
-          txtMessage = gettext('Superuser privileges are required to terminate another users query.');
-        }
-        Notify.error(txtMessage);
-        return false;
-      }
-    },
-  };
-
-  return pgAdmin.Dashboard;
-});
diff --git a/web/pgadmin/dashboard/static/js/dashboard_components.jsx b/web/pgadmin/dashboard/static/js/dashboard_components.jsx
deleted file mode 100644
index a723dd242..000000000
--- a/web/pgadmin/dashboard/static/js/dashboard_components.jsx
+++ /dev/null
@@ -1,74 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export function ChartContainer(props) {
-  return (
-    <div className="card dashboard-graph" role="object-document" tabIndex="0" aria-labelledby={props.id}>
-      <div className="card-header">
-        <div className="d-flex">
-          <div id={props.id}>{props.title}</div>
-          <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
-        </div>
-      </div>
-      <div className="card-body dashboard-graph-body">
-        <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none': '')}>
-          {props.children}
-        </div>
-        <ChartError message={props.errorMsg} />
-      </div>
-    </div>
-  );
-}
-
-ChartContainer.propTypes = {
-  id: PropTypes.string.isRequired,
-  title: PropTypes.string.isRequired,
-  legendRef: PropTypes.oneOfType([
-    PropTypes.func,
-    PropTypes.shape({ current: PropTypes.any }),
-  ]).isRequired,
-  children: PropTypes.node.isRequired,
-  errorMsg: PropTypes.string,
-};
-
-export function ChartError(props) {
-  if(props.message === null) {
-    return  <></>;
-  }
-  return (
-    <div className="pg-panel-error pg-panel-message" role="alert">{props.message}</div>
-  );
-}
-
-ChartError.propTypes = {
-  message: PropTypes.string,
-};
-
-export function DashboardRow({children}) {
-  return (
-    <div className="row dashboard-row">{children}</div>
-  );
-}
-DashboardRow.propTypes = {
-  children: PropTypes.node.isRequired,
-};
-
-export function DashboardRowCol({breakpoint, parts, children}) {
-  return (
-    <div className={`col-${breakpoint}-${parts}`}>{children}</div>
-  );
-}
-
-DashboardRowCol.propTypes = {
-  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
-  parts: PropTypes.number.isRequired,
-  children: PropTypes.node.isRequired,
-};
diff --git a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html
deleted file mode 100644
index 148ce96ab..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<div class="container-fluid dashboard-container negative-space">
-    <div id="dashboard-graphs"></div>
-    <div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
-        <div class="card-header">
-            <span id="dashboard-activity-header">{{ _('Server activity') }}</span>
-        </div>
-        <div class="card-body">
-            <div class="row">
-                <div class="col-md-9 col-12 pr-0">
-                    <ul class="nav nav-tabs" role="tablist" aria-labelledby="dashboard-activity-header">
-                        <li class="nav-item">
-                            <a class="nav-link active show" id="tab_panel_database_activity_tab" href="#tab_panel_database_activity" aria-controls="tab_database_activity"
-                                role="tab" data-toggle="tab">{{ _('Sessions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_database_locks_tab" href="#tab_panel_database_locks" aria-controls="tab_database_locks"
-                               role="tab" data-toggle="tab">{{ _('Locks') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_database_prepared_tab" href="#tab_panel_database_prepared" aria-controls="tab_database_prepared"
-                               role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
-                        </li>
-                    </ul>
-                </div>
-                <div class="col-md-3 col-12 pl-0 text-right">
-                    <div class="navtab-inline-controls">
-                        <div class="input-group">
-                            <div class="input-group-prepend">
-                                <span class="input-group-text fa fa-search" id="labelSearch" aria-label="{{ _('Search') }}"></span>
-                            </div>
-                            <input type="search" class="form-control" id="txtGridSearch" placeholder="{{ _('Search') }}" aria-describedby="labelSearch" aria-labelledby="labelSearch">
-                        </div>
-                        <button id="btn_refresh" type="button" class="btn btn-primary-icon btn-navtab-inline" title="{{ _('Refresh') }}" aria-label="{{ _('Refresh') }}">
-                            <span class="fa fa-sync-alt" aria-hidden="true"></span>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <!-- Nav tabs -->
-
-
-            <!-- Tab panes -->
-            <div class="tab-content">
-                <div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_database_activity" aria-labelledby="tab_panel_database_activity_tab">
-                    <div id="database_activity" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_locks" aria-labelledby="tab_panel_database_locks_tab">
-                    <div id="database_locks" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_prepared" aria-labelledby="tab_panel_database_prepared_tab">
-                    <div id="database_prepared" class="grid-container"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
-        {{ _('All Dashboard elements are currently disabled.') }}
-    </div>
-</div>
diff --git a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html
deleted file mode 100644
index 874a1e206..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<div class="container-fluid dashboard-container negative-space">
-    <div id="dashboard-graphs">
-    </div>
-    <div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
-        <div class="card-header">
-            <span id="server-activity-header">{{ _('Server activity') }}</span>
-        </div>
-        <div class="card-body">
-            <div class="row">
-                <div class="col-md-9 col-12 pr-0">
-                    <ul class="nav nav-tabs" role="tablist" aria-labelledby="server-activity-header">
-                        <li class="nav-item">
-                            <a class="nav-link active show" id="tab_panel_server_activity_tab" href="#tab_panel_server_activity" aria-controls="tab_server_activity"
-                                role="tab" data-toggle="tab">{{_('Sessions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_locks_tab" href="#tab_panel_server_locks" aria-controls="tab_server_locks"
-                                role="tab" data-toggle="tab">{{ _('Locks') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_prepared_tab" href="#tab_panel_server_prepared" aria-controls="tab_server_prepared"
-                                role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_config_tab" href="#tab_panel_server_config" aria-controls="tab_server_config"
-                                role="tab" data-toggle="tab">{{ _('Configuration') }}</a>
-                        </li>
-                    </ul>
-                </div>
-                <div class="col-md-3 col-12 pl-0 text-right">
-                    <div class="navtab-inline-controls">
-                        <div class="input-group">
-                            <div class="input-group-prepend">
-                                <span class="input-group-text fa fa-search" id="labelSearch"></span>
-                            </div>
-                            <input type="search" class="form-control" id="txtGridSearch" placeholder="{{ _('Search') }}" aria-label="{{ _('Search') }}" aria-describedby="labelSearch">
-                        </div>
-                        <button id="btn_refresh" type="button" class="btn btn-primary-icon btn-navtab-inline" title="{{ _('Refresh') }}" aria-label="{{ _('Refresh') }}">
-                            <span class="fa fa-sync-alt" aria-hidden="true"></span>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <!-- Nav tabs -->
-
-
-            <!-- Tab panes -->
-            <div class="tab-content">
-                <div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_server_activity" aria-labelledby="tab_panel_server_activity_tab">
-                    <div id="server_activity" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_locks" aria-labelledby="tab_panel_server_locks_tab">
-                    <div id="server_locks" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_prepared" aria-labelledby="tab_panel_server_prepared_tab">
-                    <div id="server_prepared" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_config" aria-labelledby="tab_panel_server_config_tab">
-                    <div id="server_config" class="grid-container"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
-        {{ _('All Dashboard elements are currently disabled.') }}
-    </div>
-</div>
diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql b/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql
index a9379f67b..d02d071fc 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql
@@ -12,6 +12,7 @@ SELECT
     query,
     pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
     pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
+    pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
     backend_type,
     CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
 FROM
diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql b/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql
index b0a9c5847..67cb4588f 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql
@@ -11,6 +11,7 @@ SELECT
     pg_catalog.pg_blocking_pids(pid) AS blocking_pids,
     query,
     pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
+    pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
     pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
     CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
 FROM
diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql b/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql
index 494b5adbb..3e6cf81b0 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql
@@ -10,6 +10,7 @@ SELECT
     CASE WHEN waiting THEN '{{ _('yes') }}' ELSE '{{ _('no') }}' END AS waiting,
     query,
     pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
+    pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
     pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
     CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
 FROM
diff --git a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html
deleted file mode 100644
index fc798ab19..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<div class="container-fluid negative-space">
-    <div class="dashboard-container">
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card">
-                    <div class="card-header">{{ _('Welcome') }}</div>
-                    <div class="card-body p-2">
-                        <div class="welcome-logo" aria-hidden="true">
-                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 130">
-                               <defs>
-                                  <style>.cls-1{stroke:#000;stroke-width:10.19px;}.cls-2{fill:#336791;}.cls-3,.cls-4,.cls-9{fill:none;}.cls-3,.cls-4,.cls-5,.cls-6{stroke:#fff;}.cls-3,.cls-4{stroke-linecap:round;stroke-width:3.4px;}.cls-3{stroke-linejoin:round;}.cls-4{stroke-linejoin:bevel;}.cls-5,.cls-6{fill:#fff;}.cls-5{stroke-width:1.13px;}.cls-6{stroke-width:0.57px;}.cls-7{fill:#2775b6;}.cls-8{fill:#333;}.cls-9{stroke:#333;stroke-width:3px;}</style>
-                               </defs>
-                               <title>pgAdmin_PostgreSQL</title>
-                               <g id="Layer_1" data-name="Layer 1">
-                                  <g id="Layer_3">
-                                     <path class="cls-1" d="M95.59,93.65c.77-6.44.54-7.38,5.33-6.34l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21a9,9,0,0,0,.1,2.46c-3.7,4.13-2.62,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.46,1.16,1.36,8.35,1.56,13.48s.55,9.93,1.6,12.75,2.28,10.1,12,8C88.81,119.46,95,117,95.59,93.65" />
-                                     <path class="cls-2" d="M117.17,79.2c-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21A9.41,9.41,0,0,0,59,80.22c-3.7,4.13-2.61,4.86-10,6.38s-3.08,4.29-.21,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.45,1.16,2.47,7.56,2.3,13.35s-.28,9.77.86,12.88,2.28,10.1,12,8C88.81,119.46,93,115,93.6,107.42,94,102.07,95,102.87,95,98.08l.75-2.26c.87-7.26.14-9.6,5.15-8.51l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31Z" />
-                                     <path class="cls-3" d="M66.33,83.36c-.38,13.5.09,27.09,1.41,30.39s4.15,9.73,13.88,7.64c8.12-1.74,11.08-5.11,12.36-12.55.94-5.47,2.77-20.67,3-23.79" />
-                                     <path class="cls-3" d="M54.67,15.7s-44-18-42,22.93c.44,8.7,12.48,65.87,26.84,48.6,5.25-6.32,10-11.27,10-11.27" />
-                                     <path class="cls-3" d="M78.45,12.42c-1.52.47,24.49-9.51,39.28,9.38,5.22,6.67-.83,33.94-15.31,55.42" />
-                                     <path class="cls-4" d="M102.42,77.22s.94,4.64,14.65,1.81c6-1.24,2.4,3.48-3.7,6.31-5,2.32-16.21,2.92-16.39-.29-.47-8.27,5.9-5.76,5.44-7.83-.42-1.87-3.26-3.7-5.15-8.27-1.64-4-22.57-34.58,5.8-30,1-.22-7.4-27-33.95-27.42S43.45,44.14,43.45,44.14" />
-                                     <path class="cls-3" d="M58.9,80.05c-3.7,4.13-2.61,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52,1.66-2.32,0-6-2.28-7-1.1-.46-2.57-1-4.46,1.09Z" />
-                                     <path class="cls-3" d="M58.66,80c-.38-2.44.79-5.33,2.05-8.71C62.6,66.19,67,61.11,63.47,45c-2.6-12-20-2.5-20-.87a81.48,81.48,0,0,1-.29,16c-1.41,10.06,6.4,18.57,15.39,17.7" />
-                                     <path class="cls-5" d="M54.51,43.9c-.08.55,1,2,2.45,2.23a2.62,2.62,0,0,0,2.72-1.51c.08-.56-1-1.17-2.44-1.37s-2.65.09-2.73.65Z" />
-                                     <path class="cls-6" d="M98,42.76c.07.56-1,2-2.45,2.24a2.64,2.64,0,0,1-2.73-1.52c-.07-.55,1-1.16,2.45-1.36s2.65.09,2.73.64Z" />
-                                     <path class="cls-3" d="M103.07,38.92c.24,4.36-.94,7.33-1.08,12-.22,6.74,3.21,14.46-2,22.19" />
-                                  </g>
-                                  <path class="cls-7 app-name" d="M154.72,28.15h5.16v4.16A12.84,12.84,0,0,1,163.35,29a11.17,11.17,0,0,1,6.28-1.76,11.84,11.84,0,0,1,9.08,4.09c2.48,2.72,3.73,6.62,3.73,11.67q0,10.26-5.38,14.65a12.2,12.2,0,0,1-7.95,2.79,10.78,10.78,0,0,1-6-1.56,13.55,13.55,0,0,1-3.14-3v16h-5.28Zm19.84,24.6Q177,49.65,177,43.5a17,17,0,0,0-1.09-6.44,7.51,7.51,0,0,0-7.53-5.19q-5.49,0-7.52,5.48a21.49,21.49,0,0,0-1.09,7.44A15.64,15.64,0,0,0,160.88,51a8,8,0,0,0,13.68,1.78Z" />
-                                  <path class="cls-7 app-name" d="M206,29.26a14.6,14.6,0,0,1,3,3V28.3h4.86V56.83c0,4-.58,7.13-1.75,9.44q-3.27,6.38-12.35,6.38a15.07,15.07,0,0,1-8.5-2.27,8.86,8.86,0,0,1-3.85-7.1h5.36a6,6,0,0,0,1.52,3.25q1.77,1.75,5.59,1.76,6,0,7.9-4.28,1.1-2.52,1-9a10.39,10.39,0,0,1-3.8,3.57,13.56,13.56,0,0,1-14.75-2.45q-3.81-3.62-3.81-12,0-7.89,3.84-12.31a11.85,11.85,0,0,1,9.27-4.42A11.37,11.37,0,0,1,206,29.26Zm.64,5.66a7.61,7.61,0,0,0-6.09-2.81A7.52,7.52,0,0,0,193,37.32a20.56,20.56,0,0,0-1.08,7.3c0,3.53.72,6.22,2.14,8.07a6.93,6.93,0,0,0,5.76,2.77,8.09,8.09,0,0,0,8-5.13A16.72,16.72,0,0,0,209,43.56Q209,37.73,206.62,34.92Z" />
-                                  <path class="cls-7 app-name" d="M235.16,16.34h6.58l15.62,43H251l-4.5-12.89H229.6l-4.67,12.89h-6Zm9.67,25.4-6.63-19-6.88,19Z" />
-                                  <path class="cls-7 app-name" d="M279.16,29a14.3,14.3,0,0,1,3.18,3.08V16.2h5.07V59.38h-4.75V55a11.33,11.33,0,0,1-4.35,4.19,12.51,12.51,0,0,1-5.75,1.28,11.61,11.61,0,0,1-9-4.4q-3.82-4.41-3.83-11.74a20.35,20.35,0,0,1,3.49-11.88,11.41,11.41,0,0,1,10-5A11.15,11.15,0,0,1,279.16,29ZM267.39,52.5q2.13,3.39,6.82,3.39a7.17,7.17,0,0,0,6-3.14c1.56-2.1,2.35-5.12,2.35-9s-.81-6.9-2.42-8.81a7.56,7.56,0,0,0-6-2.85,7.88,7.88,0,0,0-6.43,3c-1.64,2-2.46,5-2.46,9A15.62,15.62,0,0,0,267.39,52.5Z" />
-                                  <path class="cls-7 app-name" d="M295.29,28h5.21v4.46a17.4,17.4,0,0,1,3.4-3.37,10.24,10.24,0,0,1,5.92-1.79,9.34,9.34,0,0,1,6,1.85,9.61,9.61,0,0,1,2.34,3.1,11.37,11.37,0,0,1,4.13-3.73,11.52,11.52,0,0,1,5.33-1.22q6.33,0,8.62,4.57a15,15,0,0,1,1.23,6.62V59.38H332V37.58c0-2.09-.52-3.52-1.57-4.3a6.2,6.2,0,0,0-3.82-1.17,7.58,7.58,0,0,0-5.35,2.08c-1.49,1.38-2.24,3.7-2.24,6.94V59.38h-5.36V38.9a10.78,10.78,0,0,0-.76-4.66q-1.2-2.19-4.49-2.19A7.73,7.73,0,0,0,303,34.36c-1.63,1.54-2.45,4.34-2.45,8.38V59.38h-5.27Z" />
-                                  <path class="cls-7 app-name" d="M345.27,16.34h5.36v6h-5.36Zm0,11.81h5.36V59.38h-5.36Z" />
-                                  <path class="cls-7 app-name" d="M358.6,28h5v4.46a14,14,0,0,1,4.72-4,12.56,12.56,0,0,1,5.53-1.2c4.46,0,7.46,1.55,9,4.66a16.52,16.52,0,0,1,1.29,7.29V59.38h-5.37V39.61A10.8,10.8,0,0,0,378,35a5.15,5.15,0,0,0-5.1-2.93,10.21,10.21,0,0,0-3.08.38A8,8,0,0,0,366,35a7.66,7.66,0,0,0-1.71,3.2,21.84,21.84,0,0,0-.4,4.74V59.38H358.6Z" />
-                                  <path class="cls-8 app-tagline" d="M155.24,86.87h3.9l5.77,17,5.74-17h3.87V107h-2.6V95.1q0-.61,0-2c0-.94,0-2,0-3L166.24,107h-2.7L157.75,90v.61c0,.49,0,1.24,0,2.25s.05,1.75.05,2.22V107h-2.6Z" />
-                                  <path class="cls-8 app-tagline" d="M186.15,98.09a1.35,1.35,0,0,0,1.14-.71,2.31,2.31,0,0,0,.16-.94,2,2,0,0,0-.89-1.84A4.79,4.79,0,0,0,184,94a3.21,3.21,0,0,0-2.73,1,3.44,3.44,0,0,0-.59,1.72h-2.3A4.28,4.28,0,0,1,180.14,93,7.16,7.16,0,0,1,184.05,92a8,8,0,0,1,4.19,1,3.34,3.34,0,0,1,1.6,3.06v8.44a1.06,1.06,0,0,0,.16.62.77.77,0,0,0,.66.23l.37,0,.44-.07V107a7.38,7.38,0,0,1-.88.21,5.92,5.92,0,0,1-.82,0,2,2,0,0,1-1.84-.9,3.63,3.63,0,0,1-.43-1.36,6.16,6.16,0,0,1-2.16,1.71,6.56,6.56,0,0,1-3.1.73,4.59,4.59,0,0,1-3.33-1.24,4.09,4.09,0,0,1-1.29-3.09,4,4,0,0,1,1.27-3.16,6.16,6.16,0,0,1,3.34-1.38ZM181,104.74a2.88,2.88,0,0,0,1.84.62,5.51,5.51,0,0,0,2.52-.61,3.37,3.37,0,0,0,2-3.26v-2a3.79,3.79,0,0,1-1.16.48,10.37,10.37,0,0,1-1.39.28l-1.49.19a5.68,5.68,0,0,0-2,.56,2.18,2.18,0,0,0-1.14,2A2,2,0,0,0,181,104.74Z" />
-                                  <path class="cls-8 app-tagline" d="M193.88,92.31h2.33v2.08a6.73,6.73,0,0,1,2.2-1.85A6,6,0,0,1,201,92q3.12,0,4.21,2.18a7.73,7.73,0,0,1,.6,3.4V107h-2.5V97.73a4.87,4.87,0,0,0-.4-2.16,2.41,2.41,0,0,0-2.38-1.37,4.75,4.75,0,0,0-1.43.18,3.68,3.68,0,0,0-1.78,1.2,3.55,3.55,0,0,0-.8,1.5,10.3,10.3,0,0,0-.18,2.21V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M217.29,98.09a1.33,1.33,0,0,0,1.14-.71,2.15,2.15,0,0,0,.16-.94,2,2,0,0,0-.89-1.84,4.79,4.79,0,0,0-2.56-.56,3.24,3.24,0,0,0-2.73,1,3.44,3.44,0,0,0-.58,1.72h-2.3A4.27,4.27,0,0,1,211.28,93,7.19,7.19,0,0,1,215.2,92a8,8,0,0,1,4.19,1A3.36,3.36,0,0,1,221,96v8.44a1.14,1.14,0,0,0,.15.62.79.79,0,0,0,.67.23l.37,0,.43-.07V107a7.32,7.32,0,0,1-.87.21,6,6,0,0,1-.82,0,2,2,0,0,1-1.85-.9,3.46,3.46,0,0,1-.42-1.36,6.16,6.16,0,0,1-2.16,1.71,6.63,6.63,0,0,1-3.11.73,4.58,4.58,0,0,1-3.32-1.24,4.06,4.06,0,0,1-1.3-3.09A4,4,0,0,1,210,100a6.13,6.13,0,0,1,3.33-1.38Zm-5.18,6.65a2.91,2.91,0,0,0,1.85.62,5.47,5.47,0,0,0,2.51-.61,3.38,3.38,0,0,0,2.06-3.26v-2a3.9,3.9,0,0,1-1.16.48,10.51,10.51,0,0,1-1.4.28l-1.48.19a5.55,5.55,0,0,0-2,.56,2.17,2.17,0,0,0-1.15,2A2,2,0,0,0,212.11,104.74Z" />
-                                  <path class="cls-8 app-tagline" d="M233.16,92.9a7.05,7.05,0,0,1,1.42,1.39V92.45h2.27v13.32a10,10,0,0,1-.82,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.15,4.15,0,0,1-1.8-3.32H227a2.81,2.81,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.88,0,3.1-.66,3.68-2a11.15,11.15,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,5.93,5.93,0,0,1-2.74.54,5.79,5.79,0,0,1-4.14-1.69q-1.79-1.68-1.78-5.58a8.49,8.49,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.33,5.33,0,0,1,233.16,92.9Zm.3,2.64a3.77,3.77,0,0,0-6.38,1.12,9.73,9.73,0,0,0-.5,3.4,6.05,6.05,0,0,0,1,3.77,3.21,3.21,0,0,0,2.68,1.29,3.77,3.77,0,0,0,3.72-2.39,7.71,7.71,0,0,0,.6-3.16A6.13,6.13,0,0,0,233.46,95.54Z" />
-                                  <path class="cls-8 app-tagline" d="M249.64,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,17.44,17.44,0,0,1,.22,3.23H242.4a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3.05-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.58,6.58,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.71,8.71,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,249.64,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M256.16,92.31h2.44v2.08a8.23,8.23,0,0,1,1.58-1.57A4.79,4.79,0,0,1,263,92a4.31,4.31,0,0,1,2.81.87,4.5,4.5,0,0,1,1.1,1.44,5.27,5.27,0,0,1,1.92-1.74,5.37,5.37,0,0,1,2.49-.57,4.08,4.08,0,0,1,4,2.14,7,7,0,0,1,.58,3.09V107h-2.56V96.78a2.41,2.41,0,0,0-.73-2,2.93,2.93,0,0,0-1.79-.54,3.53,3.53,0,0,0-2.49,1,4.23,4.23,0,0,0-1.05,3.24V107h-2.5V97.4a5,5,0,0,0-.36-2.18,2.17,2.17,0,0,0-2.09-1,3.59,3.59,0,0,0-2.53,1.08c-.76.72-1.14,2-1.14,3.91V107h-2.47Z" />
-                                  <path class="cls-8 app-tagline" d="M288.53,92.72a5.47,5.47,0,0,1,2.22,1.89,6.67,6.67,0,0,1,1,2.58,17.66,17.66,0,0,1,.21,3.23H281.29a6.42,6.42,0,0,0,1,3.59,3.48,3.48,0,0,0,3,1.35,3.9,3.9,0,0,0,3.06-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5.23,5.23,0,0,1-.64,1.8,6.56,6.56,0,0,1-1.2,1.62,5.7,5.7,0,0,1-2.76,1.48,8.62,8.62,0,0,1-2,.21,6.14,6.14,0,0,1-4.61-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.91-5.72,6.24,6.24,0,0,1,5-2.21A6.58,6.58,0,0,1,288.53,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.53,3.53,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.63,4.63,0,0,0-1.2,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M295.06,92.31h2.34v2.08a6.63,6.63,0,0,1,2.2-1.85,5.91,5.91,0,0,1,2.58-.56c2.08,0,3.49.73,4.21,2.18a7.57,7.57,0,0,1,.61,3.4V107h-2.51V97.73a5,5,0,0,0-.39-2.16,2.41,2.41,0,0,0-2.38-1.37,4.86,4.86,0,0,0-1.44.18,3.7,3.7,0,0,0-1.77,1.2,3.55,3.55,0,0,0-.8,1.5,9.58,9.58,0,0,0-.19,2.21V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M311.13,88.22h2.48v4.09H316v2h-2.34v9.56a1,1,0,0,0,.52,1,2.21,2.21,0,0,0,1,.15h.38l.48,0v2a4.16,4.16,0,0,1-.88.18,7.74,7.74,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88,3.94,3.94,0,0,1-.61-2.29v-9.7h-2v-2h2Z" />
-                                  <path class="cls-8 app-tagline" d="M340.63,86.87v2.39h-6.77V107h-2.75V89.26h-6.76V86.87Z" />
-                                  <path class="cls-8 app-tagline" d="M350.31,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2A8.08,8.08,0,0,1,338.7,100a8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.6,6.6,0,0,1,350.31,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.49,3.49,0,0,0-3.25,1.72,8.07,8.07,0,0,0-1,4.15,7.05,7.05,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.35,3.35,0,0,0,348.78,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M365.88,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2,8.08,8.08,0,0,1-1.77-5.48,8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,365.88,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.46,3.46,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.54,3.54,0,0,0,3.21,1.56A3.35,3.35,0,0,0,364.35,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M370.91,86.87h2.46V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M378.53,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.86,4.86,0,0,0,2.45-.6A2,2,0,0,0,386,103a1.56,1.56,0,0,0-.84-1.43,10.63,10.63,0,0,0-2.14-.7l-2-.49a10,10,0,0,1-2.81-1,3.11,3.11,0,0,1-1.61-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.83,1.94a4.24,4.24,0,0,1,.91,2.65h-2.33A2.72,2.72,0,0,0,385,95a3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.65,1.65,0,0,0-.74,1.4,1.73,1.73,0,0,0,1,1.53,5.69,5.69,0,0,0,1.64.6l1.66.4A12.73,12.73,0,0,1,387,99.75a3.3,3.3,0,0,1,1.44,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43c-2.2,0-3.77-.5-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z" />
-                                  <path class="cls-8 app-tagline" d="M400,87.84c.58-.84,1.68-1.26,3.32-1.26l.48,0,.56,0v2.24l-.56,0h-.32c-.76,0-1.21.19-1.36.58a11.75,11.75,0,0,0-.22,3h2.46v1.94h-2.46V107h-2.43V94.32h-2V92.38h2v-2.3A4.43,4.43,0,0,1,400,87.84Z" />
-                                  <path class="cls-8 app-tagline" d="M417.23,93.77a7.38,7.38,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.18,6.18,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2,8.07,8.07,0,0,1-1.76-5.48,8.83,8.83,0,0,1,1.85-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,417.23,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.47,3.47,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.55,3.55,0,0,0,3.22,1.56A3.35,3.35,0,0,0,415.7,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M422.26,92.31h2.34v2.53A5.61,5.61,0,0,1,426,93,3.68,3.68,0,0,1,428.59,92l.24,0,.56,0v2.6a2.08,2.08,0,0,0-.41-.05l-.4,0a3.52,3.52,0,0,0-2.86,1.2,4.2,4.2,0,0,0-1,2.75V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M439.89,86.87h9a6.09,6.09,0,0,1,4.31,1.51,5.5,5.5,0,0,1,1.64,4.25,6.15,6.15,0,0,1-1.47,4.09,5.5,5.5,0,0,1-4.47,1.74h-6.27V107h-2.72Zm10.55,2.76a5.92,5.92,0,0,0-2.46-.42h-5.37v7H448a5.07,5.07,0,0,0,2.95-.78,3.1,3.1,0,0,0,1.14-2.75A3,3,0,0,0,450.44,89.63Z" />
-                                  <path class="cls-8 app-tagline" d="M468.58,93.77a7.38,7.38,0,0,1,1.95,5.55,9.51,9.51,0,0,1-1.72,5.85,6.17,6.17,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2A8.07,8.07,0,0,1,457,100a8.78,8.78,0,0,1,1.86-5.88,6.23,6.23,0,0,1,5-2.18A6.56,6.56,0,0,1,468.58,93.77Zm-1.52,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.65,3.65,0,0,0-3.55-2,3.48,3.48,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.36,3.36,0,0,0,467.06,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M475,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.93,4.93,0,0,0,2.46-.6,2,2,0,0,0,1.06-1.84,1.55,1.55,0,0,0-.85-1.43,10.4,10.4,0,0,0-2.14-.7l-2-.49a9.78,9.78,0,0,1-2.8-1,3.1,3.1,0,0,1-1.62-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.84,1.94a4.17,4.17,0,0,1,.9,2.65h-2.33a2.72,2.72,0,0,0-.6-1.51,3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.64,1.64,0,0,0-.73,1.4,1.72,1.72,0,0,0,1,1.53,5.66,5.66,0,0,0,1.65.6l1.65.4a12.83,12.83,0,0,1,3.63,1.24,3.31,3.31,0,0,1,1.43,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43q-3.3,0-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z" />
-                                  <path class="cls-8 app-tagline" d="M488,88.22h2.49v4.09h2.34v2h-2.34v9.56a1,1,0,0,0,.52,1,2.19,2.19,0,0,0,.95.15h.39l.48,0v2a4.39,4.39,0,0,1-.89.18,7.52,7.52,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88A3.94,3.94,0,0,1,488,104v-9.7h-2v-2h2Z" />
-                                  <path class="cls-8 app-tagline" d="M503.47,92.9a6.78,6.78,0,0,1,1.41,1.39V92.45h2.27v13.32a10,10,0,0,1-.81,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.1,4.1,0,0,1-1.8-3.32h2.5a2.74,2.74,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.87,0,3.1-.66,3.68-2a11.37,11.37,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,6,6,0,0,1-2.74.54,5.83,5.83,0,0,1-4.15-1.69q-1.77-1.68-1.77-5.58a8.43,8.43,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.38,5.38,0,0,1,503.47,92.9Zm.3,2.64a3.56,3.56,0,0,0-2.85-1.31,3.5,3.5,0,0,0-3.53,2.43,9.48,9.48,0,0,0-.51,3.4,6.12,6.12,0,0,0,1,3.77,3.24,3.24,0,0,0,2.69,1.29,3.75,3.75,0,0,0,3.71-2.39,7.71,7.71,0,0,0,.6-3.16A6.14,6.14,0,0,0,503.77,95.54Z" />
-                                  <path class="cls-8 app-tagline" d="M511,92.31h2.33v2.53a5.91,5.91,0,0,1,1.41-1.8A3.69,3.69,0,0,1,517.3,92l.23,0,.56,0v2.6a2.08,2.08,0,0,0-.4-.05l-.41,0a3.48,3.48,0,0,0-2.85,1.2,4.14,4.14,0,0,0-1,2.75V107H511Z" />
-                                  <path class="cls-8 app-tagline" d="M529.27,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,16.6,16.6,0,0,1,.22,3.23H522a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3-1.28,4.37,4.37,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.34,6.34,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.65,8.65,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,529.27,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M537.9,100.47a5.6,5.6,0,0,0,.78,2.78q1.3,2,4.59,2a7.9,7.9,0,0,0,2.69-.44,3.09,3.09,0,0,0,2.34-3,2.64,2.64,0,0,0-1-2.33,9.55,9.55,0,0,0-3.15-1.19l-2.64-.62a11.41,11.41,0,0,1-3.65-1.33A4.23,4.23,0,0,1,536,92.54a5.86,5.86,0,0,1,1.83-4.44A7.16,7.16,0,0,1,543,86.37a8.75,8.75,0,0,1,5.22,1.52,5.57,5.57,0,0,1,2.15,4.87h-2.56a5.12,5.12,0,0,0-.84-2.47c-.79-1.05-2.14-1.57-4.05-1.57a4.51,4.51,0,0,0-3.31,1,3.2,3.2,0,0,0-1,2.35,2.33,2.33,0,0,0,1.19,2.16,16.76,16.76,0,0,0,3.54,1.09l2.73.65a8.15,8.15,0,0,1,3,1.27,4.81,4.81,0,0,1,1.86,4.09,5.14,5.14,0,0,1-2.37,4.77,10.46,10.46,0,0,1-5.5,1.43,8.07,8.07,0,0,1-5.72-1.91,6.57,6.57,0,0,1-2-5.16Z" />
-                                  <path class="cls-8 app-tagline" d="M573.17,106.9l-1.36,1.65-3.11-2.36a11.33,11.33,0,0,1-2.43,1,10.29,10.29,0,0,1-2.85.37,9.18,9.18,0,0,1-7.32-3.06A11.71,11.71,0,0,1,553.76,97a11.9,11.9,0,0,1,2-7,8.78,8.78,0,0,1,7.69-3.72c3.54,0,6.17,1.14,7.87,3.42a11.08,11.08,0,0,1,2,6.82,14.28,14.28,0,0,1-.48,3.73,9.67,9.67,0,0,1-2.44,4.46ZM565.35,105a3.36,3.36,0,0,0,1.29-.47l-2.22-1.72,1.37-1.68,2.62,2A7.5,7.5,0,0,0,570.1,100a13.76,13.76,0,0,0,.45-3.39,8.48,8.48,0,0,0-1.85-5.7,6.35,6.35,0,0,0-5.07-2.17,6.6,6.6,0,0,0-5.15,2.08q-1.9,2.07-1.9,6.38A8.64,8.64,0,0,0,558.4,103a6.63,6.63,0,0,0,5.36,2.15A11.24,11.24,0,0,0,565.35,105Z" />
-                                  <path class="cls-8 app-tagline" d="M576.58,86.87h2.72v17.69h10.08V107h-12.8Z" />
-                                  <line class="cls-9 app-name-underline" x1="219.17" y1="66.5" x2="384.17" y2="66.5" />
-                               </g>
-                            </svg>
-                        </div>
-                        <h4>{{ _('Feature rich') }} | {{ _('Maximises PostgreSQL') }} | {{ _('Open Source') }} </h4>
-                        <p>
-                            {{ _('pgAdmin is an Open Source administration and management tool for the PostgreSQL database. It includes a graphical administration interface, an SQL query tool, a procedural code debugger and much more. The tool is designed to answer the needs of developers, DBAs and system administrators alike.') }}
-                        </p>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card ">
-                    <div class="card-header">{{ _('Quick Links') }}</div>
-                    <div class="card-body p-2">
-                        <div class="row">
-                            <div class="col-6 dashboard-link">
-                                <a href="#" onclick="pgAdmin.Dashboard.add_new_server()">
-                                    <span class="fa fa-4x dashboard-icon fa-server" aria-hidden="true"></span><br/>
-                                    {{ _('Add New Server') }}
-                                </a>
-                            </div>
-                            <div class="col-6 dashboard-link">
-                                <a href="#" onclick="pgAdmin.Preferences.show()">
-                                    <span id="mnu_preferences" class="fa fa-4x dashboard-icon fa-cogs"
-                                          aria-hidden="true"></span><br/>
-                                    {{ _('Configure pgAdmin') }}
-                                </a>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card ">
-                    <div class="card-header">{{ _('Getting Started') }}</div>
-                    <div class="card-body p-2">
-                        <div class="row">
-                        <div class="col-3 dashboard-link">
-                            <a href="http://www.postgresql.org/docs" target="postgres_help">
-                                <span class="fa fa-4x dashboard-icon dashboard-pg-doc" aria-hidden="true"></span><br/>
-                                {{ _('PostgreSQL Documentation') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="https://www.pgadmin.org" target="pgadmin_website">
-                                <span class="fa fa-4x dashboard-icon fa-globe" aria-hidden="true"></span><br/>
-                                {{ _('pgAdmin Website') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="http://planet.postgresql.org" target="planet_website">
-                                <span class="fa fa-4x dashboard-icon fa-book" aria-hidden="true"></span><br/>
-                                {{ _('Planet PostgreSQL') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="http://www.postgresql.org/community" target="postgres_website">
-                                <span class="fa fa-4x dashboard-icon fa-users" aria-hidden="true"></span><br/>
-                                {{ _('Community Support') }}
-                            </a>
-                        </div>
-                    </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
diff --git a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
index ee7ea6e46..ccb605d67 100644
--- a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
+++ b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
@@ -16,6 +16,7 @@ import Notify from '../../../../static/js/helpers/Notifier';
 import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import { getURL } from '../../../static/utils/utils';
+import Loader from 'sources/components/Loader';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
@@ -71,7 +72,7 @@ function parseData(data, node) {
 export default function Dependencies({ nodeData, item, node, ...props }) {
   const classes = useStyles();
   const [tableData, setTableData] = React.useState([]);
-
+  const [loaderText, setLoaderText] = React.useState('');
   const [msg, setMsg] = React.useState('');
   var columns = [
     {
@@ -79,14 +80,14 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
       accessor: 'type',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Name',
       accessor: 'name',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Restriction',
@@ -114,7 +115,7 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
       );
       if (node.hasDepends) {
         const api = getApiInstance();
-
+        setLoaderText('Loading...');
         api({
           url: url,
           type: 'GET',
@@ -123,8 +124,10 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
             if (res.data.length > 0) {
               let data = parseData(res.data, node);
               setTableData(data);
+              setLoaderText('');
             } else {
               setMsg(message);
+              setLoaderText('');
             }
           })
           .catch((e) => {
@@ -157,10 +160,12 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
         ></PgTable>
       ) : (
         <div className={classes.emptyPanel}>
-          <div className={classes.panelIcon}>
-            <i className="fa fa-exclamation-circle"></i>
-            <span className={classes.panelMessage}>{gettext(msg)}</span>
-          </div>
+          {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          }
         </div>
       )}
     </>
diff --git a/web/pgadmin/misc/dependents/static/js/Dependents.jsx b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
index 487e2d29b..867368b97 100644
--- a/web/pgadmin/misc/dependents/static/js/Dependents.jsx
+++ b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
@@ -16,6 +16,7 @@ import Notify from '../../../../static/js/helpers/Notifier';
 import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import { getURL } from '../../../static/utils/utils';
+import Loader from 'sources/components/Loader';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
@@ -71,7 +72,7 @@ function parseData(data, node) {
 export default function Dependents({ nodeData, item, node, ...props }) {
   const classes = useStyles();
   const [tableData, setTableData] = React.useState([]);
-
+  const [loaderText, setLoaderText] = React.useState('');
   const [msg, setMsg] = React.useState('');
 
   var columns = [
@@ -80,14 +81,14 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       accessor: 'type',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Name',
       accessor: 'name',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Restriction',
@@ -115,6 +116,7 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       );
       if (node.hasDepends && !nodeData.is_collection) {
         const api = getApiInstance();
+        setLoaderText('Loading...');
         api({
           url: url,
           type: 'GET',
@@ -125,6 +127,7 @@ export default function Dependents({ nodeData, item, node, ...props }) {
               setTableData(data);
             } else {
               setMsg(message);
+              setLoaderText('');
             }
           })
           .catch((e) => {
@@ -158,11 +161,15 @@ export default function Dependents({ nodeData, item, node, ...props }) {
         ></PgTable>
       ) : (
         <div className={classes.emptyPanel}>
-          <div className={classes.panelIcon}>
-            <i className="fa fa-exclamation-circle"></i>
-            <span className={classes.panelMessage}>{gettext(msg)}</span>
-          </div>
+          {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
+
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          }
         </div>
+
       )}
     </>
   );
diff --git a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
new file mode 100644
index 000000000..a6282f99f
--- /dev/null
+++ b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
@@ -0,0 +1,290 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+import pgAdmin from 'sources/pgadmin';
+import getApiInstance from 'sources/api_instance';
+import { makeStyles } from '@material-ui/core/styles';
+import { Box } from '@material-ui/core';
+import { Switch } from '@material-ui/core';
+import { generateCollectionURL } from '../../browser/static/js/node_ajax';
+import Notify from '../../static/js/helpers/Notifier';
+import gettext from 'sources/gettext';
+import 'wcdocker';
+import PgTable from 'sources/components/PgTable';
+import Theme from 'sources/Theme';
+import PropTypes from 'prop-types';
+import { PgIconButton } from '../../static/js/components/Buttons';
+
+const useStyles = makeStyles((theme) => ({
+  searchPadding: {
+    flex: 2.5
+  },
+  searchInput: {
+    flex: 1,
+    margin: '4 0 4 0',
+    borderLeft: 'none',
+    paddingLeft: 5
+  },
+  propertiesPanel: {
+    height: '100%'
+  },
+  autoResizer: {
+    height: '100% !important',
+    width: '100% !important',
+    background: theme.palette.grey[400],
+    padding: '8px',
+  },
+  dropButton: {
+    marginRight: '5px !important'
+  },
+}));
+
+export function CollectionNodeView({
+  node,
+  treeNodeInfo,
+  itemNodeData,
+  item,
+  pgBrowser
+}) {
+  const classes = useStyles();
+
+  const [data, setData] = React.useState([]);
+  const [selectedObject, setSelectedObject] = React.useState([]);
+  const [reload, setReload] = React.useState();
+
+
+  const [pgTableColumns, setPgTableColumns] = React.useState([
+    {
+      Header: 'properties',
+      accessor: 'Properties',
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      Header: 'value',
+      accessor: 'value',
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ]);
+
+  const getTableSelectedRows = (selRows) => {
+    setSelectedObject(selRows);
+  };
+
+  const onDrop = (type) => {
+    let selRowModels = selectedObject,
+      selRows = [],
+      selItem = pgBrowser.tree.selected(),
+      selectedItemData = selItem ? pgBrowser.tree.itemData(selItem) : null,
+      selNode = selectedItemData && pgBrowser.Nodes[selectedItemData._type],
+      url = undefined,
+      msg = undefined,
+      title = undefined;
+
+    if (selNode && selNode.type && selNode.type == 'coll-constraints') {
+      // In order to identify the constraint type, the type should be passed to the server
+      selRows = selRowModels.map((row) => ({
+        id: row.get('oid'),
+        _type: row.get('_type'),
+      }));
+    } else {
+      selRows = selRowModels.map((row) => row.original.oid);
+    }
+
+    if (selRows.length === 0) {
+      Notify.alert(
+        gettext('Drop Multiple'),
+        gettext('Please select at least one object to delete.')
+      );
+      return;
+    }
+
+    if (!selNode) return;
+
+    if (type === 'dropCascade') {
+      url = selNode.generate_url(selItem, 'delete');
+      msg = gettext(
+        'Are you sure you want to drop all the selected objects and all the objects that depend on them?'
+      );
+      title = gettext('DROP CASCADE multiple objects?');
+    } else {
+      url = selNode.generate_url(selItem, 'drop');
+      msg = gettext('Are you sure you want to drop all the selected objects?');
+      title = gettext('DROP multiple objects?');
+    }
+
+    const api = getApiInstance();
+    let dropNodeProperties = function () {
+      api
+        .delete(url, {
+          data: JSON.stringify({ ids: selRows }),
+          contentType: 'application/json; charset=utf-8',
+        })
+        .then(function (res) {
+          if (res.success == 0) {
+            pgBrowser.report_error(res.errormsg, res.info);
+          } else {
+            pgBrowser.Events.trigger(
+              'pgadmin:browser:tree:refresh',
+              selItem || pgBrowser.tree.selected(),
+              {
+                success: function () {
+                  pgBrowser.tree.select(selItem);
+                  selNode.callbacks.selected.apply(selNode, [selItem]);
+                },
+              }
+            );
+          }
+          setReload(true);
+        })
+        .catch(function (error) {
+          Notify.error(
+            gettext('Error dropping %s', selectedItemData._label.toLowerCase()),
+            error.message
+          );
+        });
+    };
+
+    if (confirm) {
+      Notify.confirm(title, msg, dropNodeProperties, null);
+    } else {
+      dropNodeProperties();
+    }
+  };
+
+  React.useEffect(() => {
+    let nodeObj =
+      pgAdmin.Browser.Nodes[itemNodeData._type.replace('coll-', '')];
+
+    let schema = nodeObj.getSchema.call(nodeObj, treeNodeInfo, itemNodeData);
+    let url = generateCollectionURL.call(nodeObj, item, 'properties');
+
+    const api = getApiInstance();
+
+    let tableColumns = [];
+    var column = {};
+
+    if (itemNodeData._type.indexOf('coll-') > -1) {
+      schema.fields.forEach((field) => {
+        if (node.columns.indexOf(field.id) > -1) {
+          if (field.label.indexOf('?') > -1) {
+            column = {
+              Header: field.label,
+              accessor: field.id,
+              sortble: true,
+              resizable: false,
+              disableGlobalFilter: false,
+              // eslint-disable-next-line react/display-name
+              Cell: ({ value }) => {
+                return (<Switch checked={Boolean(value)} value={value} disabled title={value}></Switch>);
+              }
+            };
+          } else {
+            column = {
+              Header: field.label,
+              accessor: field.id,
+              sortble: true,
+              resizable: false,
+              disableGlobalFilter: false,
+            };
+          }
+          tableColumns.push(column);
+        }
+      });
+      api({
+        url: url,
+        type: 'GET',
+      })
+        .then((res) => {
+          res.data.forEach((element) => {
+            element['icon'] = '';
+          });
+          setPgTableColumns(tableColumns);
+          setData(res.data);
+        })
+        .catch((err) => {
+          Notify.alert(
+            gettext('Failed to retrieve data from the server.'),
+            gettext(err.message)
+          );
+        });
+    }
+  }, [itemNodeData, node, item, reload]);
+
+  const customHeader = () => {
+    return (
+      <Box >
+        <PgIconButton
+          className={classes.dropButton}
+          variant="outlined"
+          icon={<i className='fa fa-trash-alt delete_multiple' aria-hidden="true" role="img"></i>}
+          aria-label="Delete/Drop"
+          title={gettext('Delete/Drop')}
+          onClick={() => {
+            onDrop('drop');
+          }}
+          disabled={
+            (selectedObject.length > 0)
+              ? !node.canDrop
+              : true
+          }
+        ></PgIconButton>
+        <PgIconButton
+          className={classes.dropButton}
+          variant="outlined"
+          icon={<i className='pg-font-icon icon-drop_cascade delete_multiple_cascade' aria-hidden="true" role="img"></i>}
+          aria-label="Drop Cascade"
+          title={gettext('Drop Cascade')}
+          onClick={() => {
+            onDrop('dropCascade');
+          }}
+          disabled={
+            (selectedObject.length > 0)
+              ? !node.canDropCascade
+              : true
+          }
+        ></PgIconButton>
+      </Box>);
+  };
+
+  return (
+    <Theme>
+      <Box className={classes.propertiesPanel}>
+        <PgTable
+          isSelectRow={true}
+          customHeader={customHeader}
+          className={classes.autoResizer}
+          columns={pgTableColumns}
+          data={data}
+          type={'panel'}
+          isSearch={false}
+          getSelectedRows={getTableSelectedRows}
+        ></PgTable>
+      </Box>
+    </Theme>
+  );
+}
+
+CollectionNodeView.propTypes = {
+  node: PropTypes.func,
+  itemData: PropTypes.object,
+  itemNodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  item: PropTypes.object,
+  pgBrowser: PropTypes.object,
+  preferences: PropTypes.object,
+  sid: PropTypes.number,
+  did: PropTypes.number,
+  row: PropTypes.object,
+  serverConnected: PropTypes.bool,
+  value: PropTypes.bool,
+};
diff --git a/web/pgadmin/misc/sql/static/js/SQL.jsx b/web/pgadmin/misc/sql/static/js/SQL.jsx
new file mode 100644
index 000000000..5eec57e8d
--- /dev/null
+++ b/web/pgadmin/misc/sql/static/js/SQL.jsx
@@ -0,0 +1,114 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React, { useEffect } from 'react';
+import { generateNodeUrl } from '../../../../browser/static/js/node_ajax';
+import gettext from 'sources/gettext';
+import PropTypes from 'prop-types';
+import Notify from '../../../../static/js/helpers/Notifier';
+import getApiInstance from 'sources/api_instance';
+import { makeStyles } from '@material-ui/core/styles';
+import CodeMirror from '../../../../static/js/components/CodeMirror';
+
+const useStyles = makeStyles((theme) => ({
+  textArea: {
+    height: '100% !important',
+    width: '100% !important',
+    background: theme.palette.grey[400],
+    overflow: 'auto !important',
+    minHeight: '100%',
+    minWidth: '100%',
+  },
+}));
+
+export default function SQL({ nodeData, node, ...props }) {
+  const classes = useStyles();
+  const [nodeSQL, setNodeSQL] = React.useState('');
+
+  const [msg, setMsg] = React.useState('');
+
+  useEffect(() => {
+    var sql = '-- ' + gettext('Please select an object in the tree view.');
+    if (node) {
+      let url = generateNodeUrl.call(
+        node,
+        props.treeNodeInfo,
+        'sql',
+        nodeData,
+        true,
+        node.url_jump_after_node
+      );
+      sql =
+        '-- ' + gettext('No SQL could be generated for the selected object.');
+
+      if (node.hasSQL) {
+        const api = getApiInstance();
+
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            if (res.data.length > 0) {
+              setNodeSQL(res.data);
+            } else {
+              setMsg(sql);
+            }
+          })
+          .catch((e) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(e.message)
+            );
+            // show failed message.
+            setMsg(gettext('Failed to retrieve data from the server.'));
+          });
+      }
+    }
+    if (sql != '') {
+      setMsg(sql);
+    }
+    return () => {
+      setNodeSQL([]);
+    };
+  }, [nodeData]);
+
+  return (
+    <>
+      {nodeSQL.length > 0 ? (
+        <CodeMirror
+          className={classes.textArea}
+          value={nodeSQL}
+          options={{
+            lineNumbers: true,
+            mode: 'text/x-pgsql',
+            readOnly: true,
+          }}
+        />
+      ) : (
+        <CodeMirror
+          className={classes.textArea}
+          value={msg}
+          options={{
+            lineNumbers: true,
+            mode: 'text/x-pgsql',
+            readOnly: true,
+          }}
+        />
+      )}
+    </>
+  );
+}
+
+SQL.propTypes = {
+  res: PropTypes.array,
+  nodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  node: PropTypes.func,
+};
diff --git a/web/pgadmin/misc/sql/static/js/sql.js b/web/pgadmin/misc/sql/static/js/sql.js
deleted file mode 100644
index 57ee3129a..000000000
--- a/web/pgadmin/misc/sql/static/js/sql.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import Notify from '../../../../static/js/helpers/Notifier';
-
-define('misc.sql', [
-  'sources/gettext', 'underscore', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.alertifyjs',
-], function(gettext, _, $, pgAdmin, pgBrowser, Alertify) {
-
-  pgBrowser.ShowNodeSQL = pgBrowser.ShowNodeSQL || {};
-
-  if (pgBrowser.ShowNodeSQL.initialized) {
-    return pgBrowser.ShowNodeSQL;
-  }
-  var wcDocker = window.wcDocker;
-
-  _.extend(pgBrowser.ShowNodeSQL, {
-    init: function() {
-      if (this.initialized) {
-        return;
-      }
-      this.initialized = true;
-      _.bindAll(this, 'showSQL', 'sqlPanelVisibilityChanged');
-
-      var sqlPanels;
-      this.sqlPanels = sqlPanels = pgBrowser.docker.findPanels('sql');
-
-      // We will listend to the visibility change of the SQL panel
-      pgBrowser.Events.on(
-        'pgadmin-browser:panel-sql:' + wcDocker.EVENT.VISIBILITY_CHANGED,
-        this.sqlPanelVisibilityChanged
-      );
-
-      pgBrowser.Events.on(
-        'pgadmin:browser:node:updated',
-        function() {
-          if (this.sqlPanels && this.sqlPanels.length) {
-            $(this.sqlPanels[0]).data('node-prop', '');
-            this.sqlPanelVisibilityChanged(this.sqlPanels[0]);
-          }
-        }, this
-      );
-
-      // Hmm.. Did we find the SQL panel, and is it visible (opened)?
-      // If that is the case - we need to listen the browser tree selection
-      // events.
-      if (sqlPanels.length == 0) {
-        pgBrowser.Events.on(
-          'pgadmin-browser:panel-sql:' + wcDocker.EVENT.INIT,
-          function() {
-            if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) {
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:selected', this.showSQL
-              );
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:reactSelected', this.reactShowSQL
-              );
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:refreshing', this.refreshSQL, this
-              );
-            }
-          }.bind(this)
-        );
-      } else {
-        if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) {
-          pgBrowser.Events.on('pgadmin-browser:tree:selected', this.showSQL);
-          pgBrowser.Events.on('pgadmin-browser:tree:reactSelected', this.reactShowSQL);
-          pgBrowser.Events.on(
-            'pgadmin-browser:tree:refreshing', this.refreshSQL, this
-          );
-        }
-      }
-    },
-    refreshSQL: function(item, data, node) {
-      var that = this,
-        cache_flag = {
-          node_type: data._type,
-          url: node.generate_url(item, 'sql', data, true),
-        };
-
-      if (_.isEqual($(that.sqlPanels[0]).data('node-prop'), cache_flag)) {
-        // Reset the current item selection
-        $(that.sqlPanels[0]).data('node-prop', '');
-        that.showSQL(item, data, node);
-      }
-    },
-    showSQL: function(item, data, node) {
-      /**
-       * We can't start fetching the SQL immediately, it is possible - the user
-       * is just using keyboards to select the node, and just traversing
-       * through. We will wait for some time before fetching the Reversed
-       * Engineering SQL.
-       **/
-
-      this.timeout && clearTimeout(this.timeout);
-
-      var that = this;
-      this.timeout = setTimeout(
-        function() {
-          var sql = '-- ' + gettext('Please select an object in the tree view.');
-          if (node) {
-            sql = '-- ' + gettext('No SQL could be generated for the selected object.');
-            var n_type = data._type,
-              url = node.generate_url(item, 'sql', data, true),
-              treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
-              cache_flag = {
-                node_type: n_type,
-                url: url,
-              };
-
-            // Avoid unnecessary reloads
-            if (_.isEqual($(that.sqlPanels[0]).data('node-prop'), cache_flag)) {
-              return;
-            }
-            // Cache the current IDs for next time
-            $(that.sqlPanels[0]).data('node-prop', cache_flag);
-
-            if (node.hasSQL) {
-
-              sql = '';
-              var timer;
-              var ajaxHook = function() {
-                $.ajax({
-                  url: url,
-                  type: 'GET',
-                  beforeSend: function(xhr) {
-                    xhr.setRequestHeader(
-                      pgAdmin.csrf_token_header, pgAdmin.csrf_token
-                    );
-                    // Generate a timer for the request
-                    timer = setTimeout(function() {
-                      // Notify user if request is taking longer than 1 second
-                      pgAdmin.Browser.editor.setValue(
-                        gettext('Retrieving data from the server...')
-                      );
-                    }, 1000);
-                  },
-                }).done(function(res) {
-                  if (pgAdmin.Browser.editor.getValue() != res) {
-                    pgAdmin.Browser.editor.setValue(res);
-                  }
-                  clearTimeout(timer);
-                }).fail(function(xhr, error, message) {
-                  var _label = treeHierarchy[n_type].label;
-                  pgBrowser.Events.trigger(
-                    'pgadmin:node:retrieval:error', 'sql', xhr, error, message, item
-                  );
-                  if (!Alertify.pgHandleItemError(xhr, error, message, {
-                    item: item,
-                    info: treeHierarchy,
-                  })) {
-                    Notify.pgNotifier(
-                      error, xhr,
-                      gettext('Error retrieving the information - %s', message || _label),
-                      function(msg) {
-                        if(msg === 'CRYPTKEY_SET') {
-                          ajaxHook();
-                        } else {
-                          console.warn(arguments);
-                        }
-                      }
-                    );
-                  }
-                });
-              };
-              ajaxHook();
-            }
-          }
-
-          if (sql != '') {
-            pgAdmin.Browser.editor.setValue(sql);
-          }
-        }, 400);
-    },
-    sqlPanelVisibilityChanged: function(panel) {
-      if (panel.isVisible()) {
-        var t = pgBrowser.tree,
-          i = t.selected(),
-          d = i && t.itemData(i),
-          n = i && d && pgBrowser.Nodes[d._type];
-
-        pgBrowser.ShowNodeSQL.showSQL.apply(pgBrowser.ShowNodeSQL, [i, d, n]);
-
-        // We will start listening the tree selection event.
-        pgBrowser.Events.on('pgadmin-browser:tree:selected', pgBrowser.ShowNodeSQL.showSQL);
-        pgBrowser.Events.on(
-          'pgadmin-browser:tree:refreshing', pgBrowser.ShowNodeSQL.refreshSQL, this
-        );
-      } else {
-        // We don't need to listen the tree item selection event.
-        pgBrowser.Events.off('pgadmin-browser:tree:selected', pgBrowser.ShowNodeSQL.showSQL);
-        pgBrowser.Events.off(
-          'pgadmin-browser:tree:refreshing', pgBrowser.ShowNodeSQL.refreshSQL, this
-        );
-      }
-    },
-  });
-
-  return pgBrowser.ShowNodeSQL;
-});
diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
index caf635351..305262680 100644
--- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx
+++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
@@ -17,7 +17,7 @@ import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import sizePrettify from 'sources/size_prettify';
 import { getURL } from '../../../static/utils/utils';
-
+import Loader from 'sources/components/Loader';
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
@@ -37,12 +37,18 @@ const useStyles = makeStyles((theme) => ({
     marginLeft: '0.5rem',
     fontSize: '0.875rem',
   },
+  loading: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+    colour: theme.palette.grey[400]
+  },
   autoResizer: {
     height: '100% !important',
     width: '100% !important',
     background: theme.palette.grey[400],
     padding: '7.5px',
-    overflow: 'auto !important',
+    overflowX: 'auto !important',
+    overflowY: 'hidden !important',
     minHeight: '100%',
     minWidth: '100%',
   },
@@ -58,7 +64,7 @@ function getColumn(data, singleLineStatistics) {
           accessor: row.name,
           sortble: true,
           resizable: false,
-          disableGlobalFilter: true,
+          disableGlobalFilter: false,
         };
         columns.push(column);
       });
@@ -71,14 +77,14 @@ function getColumn(data, singleLineStatistics) {
         accessor: 'name',
         sortble: true,
         resizable: false,
-        disableGlobalFilter: true,
+        disableGlobalFilter: false,
       },
       {
         Header: 'Value',
         accessor: 'value',
         sortble: true,
         resizable: false,
-        disableGlobalFilter: true,
+        disableGlobalFilter: false,
       },
     ];
   }
@@ -142,20 +148,21 @@ export default function Statistics({ nodeData, item, node, ...props }) {
   const [tableData, setTableData] = React.useState([]);
 
   const [msg, setMsg] = React.useState('');
+  const [loaderText, setLoaderText] = React.useState('');
   const [columns, setColumns] = React.useState([
     {
       Header: 'Statictics',
       accessor: 'name',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Value',
       accessor: 'value',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
   ]);
 
@@ -170,6 +177,7 @@ export default function Statistics({ nodeData, item, node, ...props }) {
 
       const api = getApiInstance();
       if (node.hasStatistics) {
+        setLoaderText('Loading...');
         api({
           url: url,
           type: 'GET',
@@ -180,6 +188,7 @@ export default function Statistics({ nodeData, item, node, ...props }) {
             if (!_.isUndefined(colData)) {
               setColumns(colData);
             }
+            setLoaderText('');
           })
           .catch((e) => {
             Notify.alert(
@@ -187,10 +196,12 @@ export default function Statistics({ nodeData, item, node, ...props }) {
               gettext(e.message)
             );
             // show failed message.
+            setLoaderText('');
             setMsg(gettext('Failed to retrieve data from the server.'));
           });
       } else {
-        setMsg(message);
+        setLoaderText('');
+        setMsg('No statistics are available for the selected object.');
       }
     }
     if (message != '') {
@@ -213,10 +224,12 @@ export default function Statistics({ nodeData, item, node, ...props }) {
         ></PgTable>
       ) : (
         <div className={classes.emptyPanel}>
-          <div className={classes.panelIcon}>
-            <i className="fa fa-exclamation-circle"></i>
-            <span className={classes.panelMessage}>{gettext(msg)}</span>
-          </div>
+          {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          }
         </div>
       )}
     </>
diff --git a/web/pgadmin/static/js/Theme/standard.js b/web/pgadmin/static/js/Theme/standard.js
index ddc9cd735..8cf463a71 100644
--- a/web/pgadmin/static/js/Theme/standard.js
+++ b/web/pgadmin/static/js/Theme/standard.js
@@ -85,6 +85,7 @@ export default function(basicSettings) {
         padding: '5px 8px',
       },
       borderColor: '#dde0e6',
+      colorFg: '#222222',
       loader: {
         backgroundColor: fade('#000', 0.65),
         color: '#fff',
@@ -102,6 +103,7 @@ export default function(basicSettings) {
       toggleBtnBg: '#000',
       editorToolbarBg: '#ebeef3',
       datagridBg: '#fff',
+
     }
   });
 }
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index 1b5179ac0..d17538d76 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -8,13 +8,26 @@
 //////////////////////////////////////////////////////////////
 
 import React from 'react';
-import { useTable, useRowSelect, useSortBy, useResizeColumns, useFlexLayout, useGlobalFilter } from 'react-table';
-import { FixedSizeList } from 'react-window';
+import {
+  useTable,
+  useRowSelect,
+  useSortBy,
+  useResizeColumns,
+  useFlexLayout,
+  useGlobalFilter,
+  useExpanded,
+} from 'react-table';
+import { VariableSizeList } from 'react-window';
 import { makeStyles } from '@material-ui/core/styles';
 import clsx from 'clsx';
 import PropTypes from 'prop-types';
 import AutoSizer from 'react-virtualized-auto-sizer';
 import { Checkbox } from '@material-ui/core';
+import { InputText } from './FormComponents';
+import FormView from 'sources/SchemaView';
+import { Box } from '@material-ui/core';
+import { _ } from 'core-js';
+
 /* eslint-disable react/display-name */
 const useStyles = makeStyles((theme) => ({
   root: {
@@ -29,22 +42,68 @@ const useStyles = makeStyles((theme) => ({
     width: '100% !important',
   },
   fixedSizeList: {
-    // position: 'relative',
     direction: 'ltr',
     overflowX: 'hidden !important',
-    overflow: 'overlay !important'
+    overflow: 'overlay !important',
+  },
+  customHeader:{
+    marginTop: '12px',
+    marginLeft: '4px'
+  },
+  searchBox: {
+    marginBottom: '5px',
+    display: 'flex',
+    background: '#fff'
+  },
+  tableContentWidth: {
+    width: 'calc(100% - 3px)',
+    height: 'auto !important'
+  },
+  tableContent: {
+    height: 'auto',
+    maxHeight: '260px'
+
+  },
+  searchPadding: {
+    flex: 2.5
+  },
+  checkbox: {
+    minWidth: 10
+  },
+  searchInput: {
+    flex: 1,
+    marginTop: 8,
+    borderLeft: 'none',
+    paddingLeft: 5,
+    marginRight: 8,
+    marginBottom: 8,
+
   },
   table: {
-    flexGrow:1,
-    minHeight:0,
+    flexGrow: 1,
+    minHeight: 0,
     borderSpacing: 0,
     width: '100%',
     overflow: 'hidden',
     borderRadius: theme.shape.borderRadius,
   },
-  extraTable:{
-    backgroundColor: theme.palette.grey[400],
-    flexGrow:1,
+  pgTableHeadar: {
+    display: 'flex',
+    flexGrow: 1,
+    overflow: 'hidden !important',
+    height: '100% !important',
+    flexDirection: 'column'
+  },
+
+  expandedForm: {
+    borderTopWidth: theme.spacing(0.5),
+    borderBottemWidth: theme.spacing(0.5),
+    borderStyle: 'solid ',
+    borderColor: theme.palette.grey[400],
+    position: 'relative',
+    height: '100%',
+    visibility: 'visible',
+    maxHeight: '260px'
   },
 
   tableCell: {
@@ -54,15 +113,15 @@ const useStyles = makeStyles((theme) => ({
     ...theme.mixins.panelBorder.right,
     position: 'relative',
     overflow: 'hidden',
+    height: '35px',
     textOverflow: 'ellipsis',
     whiteSpace: 'nowrap',
     backgroundColor: theme.otherVars.tableBg,
     // ...theme.mixins.panelBorder.top,
     ...theme.mixins.panelBorder.left,
-
   },
   selectCell: {
-    textAlign: 'center'
+    textAlign: 'center',
   },
   tableCellHeader: {
     fontWeight: theme.typography.fontWeightBold,
@@ -93,13 +152,28 @@ const useStyles = makeStyles((theme) => ({
     paddingTop: '0.35em',
     height: 35,
     backgroundPosition: '1%',
-  }
-}),
-);
+  },
+}));
 
 export default function PgTable({ columns, data, isSelectRow, ...props }) {
   // Use the state and functions returned from useTable to build your UI
   const classes = useStyles();
+  const [searchVal, setSearchVal] = React.useState('');
+  const tableRef = React.useRef();
+  const rowHeights = React.useRef({});
+  const rowRef = React.useRef({});
+
+  function getRowHeight(index, size) {
+    return rowHeights.current[index] + size || 35;
+  }
+
+  const setRowHeight = React.useCallback((index, size) => {
+    if(tableRef.current) {
+      tableRef.current.resetAfterIndex(0);
+      rowHeights.current = { ...rowHeights.current, [index]: size };
+    }
+  }, []);
+
   const defaultColumn = React.useMemo(
     () => ({
       minWidth: 150,
@@ -119,7 +193,9 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
         <>
           <Checkbox
             color="primary"
-            ref={resolvedRef} {...rest} />
+            ref={resolvedRef} {...rest}
+            className={classes.checkbox}
+          />
         </>
       );
     },
@@ -141,9 +217,9 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     rows,
     prepareRow,
     selectedFlatRows,
-    state: { selectedRowIds },
+    state: { selectedRowIds, expanded },
     setGlobalFilter,
-    setHiddenColumns
+    setHiddenColumns,
   } = useTable(
     {
       columns,
@@ -153,11 +229,12 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     },
     useGlobalFilter,
     useSortBy,
+    useExpanded,
     useRowSelect,
     useResizeColumns,
     useFlexLayout,
-    hooks => {
-      hooks.visibleColumns.push(CLOUMNS => {
+    (hooks) => {
+      hooks.visibleColumns.push((CLOUMNS) => {
         if (isSelectRow) {
           return [
             // Let's make a column for selection
@@ -195,6 +272,11 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     }
   );
 
+  React.useEffect(()=>{    
+    tableRef.current?.resetAfterIndex(0);
+  },[expanded]);
+
+
   React.useEffect(() => {
     setHiddenColumns(
       columns
@@ -222,28 +304,40 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
   }, [selectedRowIds]);
 
   React.useEffect(() => {
-    setGlobalFilter(props.searchText || undefined);
-  }, [props.searchText]);
-
+    setGlobalFilter(searchVal || undefined);
+  }, [searchVal]);
 
   const RenderRow = React.useCallback(
     ({ index, style }) => {
       const row = rows[index];
       prepareRow(row);
       return (
-        <div
-          {...row.getRowProps({
-            style,
-          })}
-          className={classes.tr}
-        >
-          {row.cells.map((cell) => {
-            return (
-              <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classes.tableCell, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={cell.value}>
-                {cell.render('Cell')}
-              </div>
-            );
-          })}
+        <div className={classes.tableContentWidth} style={style} key={row.id}>
+          <div
+            {...row.getRowProps()}
+            className={classes.tr}
+          >
+            {row.cells.map((cell) => {
+              return (
+                <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classes.tableCell, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={cell.value}>
+                  {cell.render('Cell')}
+                </div>
+              );
+            })}
+          </div>
+          {!_.isUndefined(row) && row.isExpanded && (
+            <Box key={row.id} className={classes.expandedForm} ref={rowRef} style={{height: rowHeights.current[index]}}>
+              <FormView
+                getInitData={() => {
+                  /*This is intentional (SonarQube)*/
+                }}
+                viewHelperProps={{ mode: 'properties' }}
+                schema={props.schema}
+                showFooter={false}
+                onDataChange={() => { }}
+              />
+            </Box>
+          )}          
         </div>
       );
     },
@@ -251,70 +345,96 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
   );
   // Render the UI for your table
   return (
-    <AutoSizer className={(props.type ==='panel' ? props.className: classes.autoResizer)}>
-      {({ height}) => (
-        <div {...getTableProps()} className={classes.table}>
-          <div>
-            {headerGroups.map((headerGroup) => (
-              <div key={''} {...headerGroup.getHeaderGroupProps()}>
-                {headerGroup.headers.map((column) => (
-                  <div
-                    key={column.id}
-                    {...column.getHeaderProps()}
-                    className={clsx(
-                      classes.tableCellHeader,
-                      column.className
-                    )}
-                  >
+    <Box className={classes.pgTableHeadar}>
+      <Box className={classes.searchBox}>
+        {props.customHeader && (<Box className={classes.customHeader}> <props.customHeader /></Box>)}
+        <Box className={classes.searchPadding}></Box>
+        <InputText
+          placeholder={'Search'}
+          className={classes.searchInput}
+          value={searchVal}
+          onChange={(val) => {
+            setSearchVal(val);
+          }}
+        />
+      </Box>
+      
+      <AutoSizer
+        className={props.type === 'panel' ? props.className : classes.autoResizer}
+      >
+        {({ height }) => (
+          <div {...getTableProps()} className={classes.table}>
+            <div>
+              {headerGroups.map((headerGroup) => (
+                <div key={''} {...headerGroup.getHeaderGroupProps()}>
+                  {headerGroup.headers.map((column) => (
                     <div
-                      {...(column.sortble
-                        ? column.getSortByToggleProps()
-                        : {})}
+                      key={column.id}
+                      {...column.getHeaderProps()}
+                      className={clsx(classes.tableCellHeader, column.className)}
                     >
-                      {column.render('Header')}
-                      <span>
-                        {column.isSorted
-                          ? column.isSortedDesc
-                            ? ' 🔽'
-                            : ' 🔼'
-                          : ''}
-                      </span>
-                      {column.resizable && (
-                        <div
-                          {...column.getResizerProps()}
-                          className={classes.resizer}
-                        />
-                      )}
+                      <div
+                        {...(column.sortble ? column.getSortByToggleProps() : {})}
+                      >
+                        {column.render('Header')}
+                        <span>
+                          {column.isSorted
+                            ? column.isSortedDesc
+                              ? ' 🔽'
+                              : ' 🔼'
+                            : ''}
+                        </span>
+                        {column.resizable && (
+                          <div
+                            {...column.getResizerProps()}
+                            className={classes.resizer}
+                          />
+                        )}
+                      </div>
                     </div>
-                  </div>
-                ))}
-                {/* <span className={classes.extraTable}></span> */}
-              </div>
-            ))}
-          </div>
+                  ))}
+                </div>
+              ))}
+            </div>
+
+            <div {...getTableBodyProps()} >
+              <VariableSizeList
+                ref={tableRef}
+                className={classes.fixedSizeList}
+                height={height}
+                itemCount={rows.length}
 
-          <div {...getTableBodyProps()} className={classes}>
-            <FixedSizeList
-              className={classes.fixedSizeList}
-              height={height - 75}
-              itemCount={rows.length}
-              itemSize={35} 
-              sorted={props?.sortOptions}
-            >
-              {RenderRow}
-            </FixedSizeList>
+                itemSize={(i) => {
+                  if (_.isUndefined(rows[i].isExpanded)) {
+                    rows[i].isExpanded = false;
+                  }
+                  if (rowRef.current && rows[i].isExpanded) {
+                    setRowHeight(i, rowRef.current.offsetHeight);
+                  }
+                  return rows[i].isExpanded ? getRowHeight(i, 35): 35;
+                }}
+                sorted={props?.sortOptions}
+              >
+                {RenderRow}
+                
+              </VariableSizeList>
+            </div>
           </div>
-        </div>
-      )}
-    </AutoSizer>
+        )}
+      </AutoSizer>
+    </Box>
   );
 }
 
 PgTable.propTypes = {
   stepId: PropTypes.number,
   height: PropTypes.number,
+  customHeader: PropTypes.func,
   className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
+  children: PropTypes.oneOfType([
+    PropTypes.arrayOf(PropTypes.node),
+    PropTypes.node,
+  ]),
   getToggleAllRowsSelectedProps: PropTypes.func,
   columns: PropTypes.array,
   data: PropTypes.array,
@@ -324,8 +444,6 @@ PgTable.propTypes = {
   getSelectedRows: PropTypes.func,
   searchText: PropTypes.string,
   type: PropTypes.string,
-  sortOptions:  PropTypes.array,
-
+  sortOptions: PropTypes.array,
+  schema: PropTypes.object
 };
-
-
diff --git a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
index a0f38ea2f..015c3939d 100644
--- a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
+++ b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
@@ -17,7 +17,7 @@ import Wizard from '../../../../static/js/helpers/wizard/Wizard';
 import WizardStep from '../../../../static/js/helpers/wizard/WizardStep';
 import PgTable from 'sources/components/PgTable';
 import { getNodePrivilegeRoleSchema } from '../../../../../pgadmin/browser/server_groups/servers/static/js/privilege.ui.js';
-import { InputSQL, InputText, FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
+import { InputSQL, FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
 import getApiInstance from '../../../../static/js/api_instance';
 import SchemaView from '../../../../static/js/SchemaView';
 import clsx from 'clsx';
@@ -117,7 +117,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
   const [selectedObject, setSelectedObject] = React.useState([]);
   const [selectedAcl, setSelectedAcl] = React.useState({});
   const [msqlData, setSQL] = React.useState('');
-  const [searchVal, setSearchVal] = React.useState('');
   const [loaderText, setLoaderText] = React.useState('');
   const [tablebData, setTableData] = React.useState([]);
   const [privOptions, setPrivOptions] = React.useState({});
@@ -314,17 +313,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
       loaderText={loaderText}
     >
       <WizardStep stepId={0}>
-        <Box className={classes.searchBox}>
-          <Box className={classes.searchPadding}></Box>
-          <InputText
-            placeholder={'Search'}
-            className={classes.searchInput}
-            value={searchVal}
-            onChange={(val) => {
-              setSearchVal(val);}
-            }>
-          </InputText>
-        </Box>
         <Box className={classes.panelContent}>
           <PgTable
             className={classes.table}
@@ -332,7 +320,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
             columns={columns}
             data={tablebData}
             isSelectRow={true}
-            searchText={searchVal}
             getSelectedRows={getTableSelectedRows}>
           </PgTable>
         </Box>
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 3f9c5f8f4..ed9ad4472 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -469,10 +469,8 @@ module.exports = [{
         options: {
           type: 'commonjs',
           imports: [
-            'pure|pgadmin.dashboard',
             'pure|pgadmin.browser.quick_search',
             'pure|pgadmin.tools.user_management',
-            'pure|pgadmin.browser.object_sql',
             'pure|pgadmin.browser.bgprocess',
             'pure|pgadmin.node.server_group',
             'pure|pgadmin.node.server',
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index a2e8f28e7..f9af1531f 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -208,14 +208,13 @@ var webpackShimConfig = {
     'pgadmin.browser.dialog': path.join(__dirname, './pgadmin/browser/static/js/dialog'),
     'pgadmin.browser.node': path.join(__dirname, './pgadmin/browser/static/js/node'),
     'pgadmin.browser.node.ui': path.join(__dirname, './pgadmin/browser/static/js/node.ui'),
-    'pgadmin.browser.object_sql': path.join(__dirname, './pgadmin/misc/sql/static/js/sql'),
     'pgadmin.browser.panel': path.join(__dirname, './pgadmin/browser/static/js/panel'),
     'pgadmin.browser.toolbar': path.join(__dirname, './pgadmin/browser/static/js/toolbar'),
     'pgadmin.browser.server.privilege': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/privilege'),
     'pgadmin.browser.server.variable': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/variable'),
     'pgadmin.browser.utils': '/browser/js/utils',
     'pgadmin.browser.wizard': path.join(__dirname, './pgadmin/browser/static/js/wizard'),
-    'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/dashboard'),
+    'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/Dashboard'),
     'pgadmin.datagrid': path.join(__dirname, './pgadmin/tools/datagrid/static/js/datagrid'),
     'pgadmin.file_manager': path.join(__dirname, './pgadmin/misc/file_manager/static/js/file_manager'),
     'pgadmin.file_utility': path.join(__dirname, './pgadmin/misc/file_manager/static/js/utility'),


^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
@ 2022-03-28 06:28       ` Akshay Joshi <[email protected]>
  2022-03-30 06:00         ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Akshay Joshi @ 2022-03-28 06:28 UTC (permalink / raw)
  To: Pradip Parkale <[email protected]>; +Cc: Aditya Toshniwal <[email protected]>; pgadmin-hackers

Hi Pradip

Following are the review comments (GUI):

   - Catalog objects should not be drop or drop cascade. Remove checkboxes
   from the properties panel.
   -  Database column should be there for the 'Server Activity' table all
   tabs when the server is selected. When the database is selected it should
   be hidden.
   - Rename 'Lock' tab to 'Locks'.
   - Remove extra column 'Waiting' which was not there originally.
   - 'Server Activity' -> Sessions-> Details for the last record is not
   readable. Fix the scroll bar issue. Same with the Configuration tab last
   4-5 records are not readable.
   -  Select and expand the first and second records, the rest of the
   records are not visible, again seems to be a scroll bar issue.
   - 'Server Activity' -> Locks, "Granted?" column is empty, not showing
   any value.
   - Set the width of the column appropriately for all the tabs, for
   example, unit columns (in Configuration tab) width should be less, so that
   data on the other columns are more readable. Check all the tabs and set
   them appropriately
   - Faced "Request failed with status code 404" error. Select database
   server from browser tree and then select 'Server Activity'
   -> Configuration. Now select any database, you will get the error.
   - Properties panel size of the column having checkboxes should be less,
   compare with existing behavior.
   - Properties panel should show the message '*No Properties are available
   for the selected object*' if the respective collection node does not
   have children.



On Mon, Mar 28, 2022 at 10:08 AM Pradip Parkale <
[email protected]> wrote:

> Hi,
> Here is the updated patch. This patch includes the fix for #7215
> <https://redmine.postgresql.org/issues/7215;.
>
> On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
> [email protected]> wrote:
>
>> Hi Aditya,
>> Please ignore the previous email, find the updated patch attached.
>>
>> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
>> [email protected]> wrote:
>>
>>> Hi Aditya,
>>> Please find the updated patch.
>>>
>>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>>> [email protected]> wrote:
>>>
>>>> Hi Pradip,
>>>>
>>>> I did some basic usage and review and found below issues:
>>>> 1. The code fails if you refresh the page and go to properties, when no
>>>> node is selected.
>>>> 2. I found below UI issues on selecting a database node. Also, checkbox
>>>> column is too wide.
>>>> [image: image.png]
>>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>>
>>>> +
>>>>
>>>> +              ReactDOM.render(
>>>>
>>>> +                <Theme>
>>>>
>>>> +                  <CollectionNodeView
>>>>
>>>> +                    node={node}
>>>>
>>>> +                    treeNodeInfo={treeNodeInfo}
>>>>
>>>> +                    item={item}
>>>>
>>>> +                    itemNodeData={d}
>>>>
>>>> +                    pgBrowser={pgBrowser}
>>>>
>>>> +                  ></CollectionNodeView>
>>>>
>>>> +                </Theme>,
>>>>
>>>> +                b.panels['properties'].panel.$container[0]
>>>>
>>>> +              );
>>>>
>>>> 4. I have seen a lot of commented codes. Few samples:
>>>>
>>>> +              // if (that.canHide) {
>>>>
>>>>
>>>> +              //
>>>> pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
>>>>
>>>> +
>>>>
>>>> +              //     removePanelView($container[0]);
>>>>
>>>> +              // });
>>>>
>>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please move
>>>> it to a file and import it.
>>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>>> 8. Rename Sql.jsx to SQL.jsx
>>>> 9. The search is not working. It filters all.
>>>> 10. If there is huge data then it should show some spinner.
>>>> 11. Delete buttons should be disabled if no object is selected.
>>>> 12. Delete buttons and search box should be on the same line.
>>>>
>>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Aditya
>>>>>
>>>>> Can you please review/test it?
>>>>>
>>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Hackers,
>>>>>>
>>>>>> Please find the attached patch for #7132
>>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>>> collection, Dashboard and SQL panel in React.
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Thanks & Regards,
>>>>>> Pradip Parkale
>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> *Thanks & Regards*
>>>>> *Akshay Joshi*
>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>
>>>>> *Mobile: +91 976-788-8246*
>>>>>
>>>>
>>>>
>>>> --
>>>> Thanks,
>>>> Aditya Toshniwal
>>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>>> <http://edbpostgres.com;
>>>> "Don't Complain about Heat, Plant a TREE"
>>>>
>>>
>>>
>>> --
>>> Thanks & Regards,
>>> Pradip Parkale
>>> Software Engineer | EnterpriseDB Corporation
>>>
>>
>>
>> --
>> Thanks & Regards,
>> Pradip Parkale
>> Software Engineer | EnterpriseDB Corporation
>>
>
>
> --
> Thanks & Regards,
> Pradip Parkale
> Software Engineer | EnterpriseDB Corporation
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-28 06:28       ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
@ 2022-03-30 06:00         ` Pradip Parkale <[email protected]>
  2022-03-30 06:38           ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Pradip Parkale @ 2022-03-30 06:00 UTC (permalink / raw)
  To: Akshay Joshi <[email protected]>; +Cc: Aditya Toshniwal <[email protected]>; pgadmin-hackers

Hi Akhay,

Please find the updated patch.I have fixed all the issues.

On Mon, Mar 28, 2022 at 11:58 AM Akshay Joshi <[email protected]>
wrote:

> Hi Pradip
>
> Following are the review comments (GUI):
>
>    - Catalog objects should not be drop or drop cascade. Remove
>    checkboxes from the properties panel.
>    -  Database column should be there for the 'Server Activity' table all
>    tabs when the server is selected. When the database is selected it should
>    be hidden.
>    - Rename 'Lock' tab to 'Locks'.
>    - Remove extra column 'Waiting' which was not there originally.
>    - 'Server Activity' -> Sessions-> Details for the last record is not
>    readable. Fix the scroll bar issue. Same with the Configuration tab last
>    4-5 records are not readable.
>    -  Select and expand the first and second records, the rest of the
>    records are not visible, again seems to be a scroll bar issue.
>    - 'Server Activity' -> Locks, "Granted?" column is empty, not showing
>    any value.
>    - Set the width of the column appropriately for all the tabs, for
>    example, unit columns (in Configuration tab) width should be less, so that
>    data on the other columns are more readable. Check all the tabs and set
>    them appropriately
>    - Faced "Request failed with status code 404" error. Select database
>    server from browser tree and then select 'Server Activity'
>    -> Configuration. Now select any database, you will get the error.
>    - Properties panel size of the column having checkboxes should be
>    less, compare with existing behavior.
>    - Properties panel should show the message '*No Properties are
>    available for the selected object*' if the respective collection node
>    does not have children.
>
>
>
> On Mon, Mar 28, 2022 at 10:08 AM Pradip Parkale <
> [email protected]> wrote:
>
>> Hi,
>> Here is the updated patch. This patch includes the fix for #7215
>> <https://redmine.postgresql.org/issues/7215;.
>>
>> On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
>> [email protected]> wrote:
>>
>>> Hi Aditya,
>>> Please ignore the previous email, find the updated patch attached.
>>>
>>> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
>>> [email protected]> wrote:
>>>
>>>> Hi Aditya,
>>>> Please find the updated patch.
>>>>
>>>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Pradip,
>>>>>
>>>>> I did some basic usage and review and found below issues:
>>>>> 1. The code fails if you refresh the page and go to properties, when
>>>>> no node is selected.
>>>>> 2. I found below UI issues on selecting a database node. Also,
>>>>> checkbox column is too wide.
>>>>> [image: image.png]
>>>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>>>
>>>>> +
>>>>>
>>>>> +              ReactDOM.render(
>>>>>
>>>>> +                <Theme>
>>>>>
>>>>> +                  <CollectionNodeView
>>>>>
>>>>> +                    node={node}
>>>>>
>>>>> +                    treeNodeInfo={treeNodeInfo}
>>>>>
>>>>> +                    item={item}
>>>>>
>>>>> +                    itemNodeData={d}
>>>>>
>>>>> +                    pgBrowser={pgBrowser}
>>>>>
>>>>> +                  ></CollectionNodeView>
>>>>>
>>>>> +                </Theme>,
>>>>>
>>>>> +                b.panels['properties'].panel.$container[0]
>>>>>
>>>>> +              );
>>>>>
>>>>> 4. I have seen a lot of commented codes. Few samples:
>>>>>
>>>>> +              // if (that.canHide) {
>>>>>
>>>>>
>>>>> +              //
>>>>> pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
>>>>>
>>>>> +
>>>>>
>>>>> +              //     removePanelView($container[0]);
>>>>>
>>>>> +              // });
>>>>>
>>>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please move
>>>>> it to a file and import it.
>>>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>>>> 8. Rename Sql.jsx to SQL.jsx
>>>>> 9. The search is not working. It filters all.
>>>>> 10. If there is huge data then it should show some spinner.
>>>>> 11. Delete buttons should be disabled if no object is selected.
>>>>> 12. Delete buttons and search box should be on the same line.
>>>>>
>>>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Aditya
>>>>>>
>>>>>> Can you please review/test it?
>>>>>>
>>>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Hackers,
>>>>>>>
>>>>>>> Please find the attached patch for #7132
>>>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>>>> collection, Dashboard and SQL panel in React.
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Thanks & Regards,
>>>>>>> Pradip Parkale
>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> *Thanks & Regards*
>>>>>> *Akshay Joshi*
>>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>>
>>>>>> *Mobile: +91 976-788-8246*
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Thanks,
>>>>> Aditya Toshniwal
>>>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>>>> <http://edbpostgres.com;
>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>
>>>>
>>>>
>>>> --
>>>> Thanks & Regards,
>>>> Pradip Parkale
>>>> Software Engineer | EnterpriseDB Corporation
>>>>
>>>
>>>
>>> --
>>> Thanks & Regards,
>>> Pradip Parkale
>>> Software Engineer | EnterpriseDB Corporation
>>>
>>
>>
>> --
>> Thanks & Regards,
>> Pradip Parkale
>> Software Engineer | EnterpriseDB Corporation
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
> *pgAdmin Hacker | Principal Software Architect*
> *EDB Postgres <http://edbpostgres.com>*
>
> *Mobile: +91 976-788-8246*
>


-- 
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

  [application/octet-stream] RM7132_v4.patch (372.4K, 4-RM7132_v4.patch)
  download | inline diff:
diff --git a/web/package.json b/web/package.json
index 4200b1f82..2379e9188 100644
--- a/web/package.json
+++ b/web/package.json
@@ -83,10 +83,16 @@
     "@date-io/date-fns": "1.x",
     "@emotion/sheet": "^1.0.1",
     "@fortawesome/fontawesome-free": "^5.14.0",
+    "@fortawesome/fontawesome-svg-core": "^6.1.0",
+    "@fortawesome/free-regular-svg-icons": "^6.1.0",
+    "@fortawesome/free-solid-svg-icons": "^6.1.0",
+    "@fortawesome/react-fontawesome": "^0.1.18",
     "@material-ui/core": "4.11.0",
     "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "4.0.0-alpha.58",
     "@material-ui/pickers": "^3.2.10",
+    "@mui/icons-material": "^5.4.2",
+    "@mui/material": "^5.4.3",
     "@projectstorm/react-diagrams": "^6.6.1",
     "@simonwep/pickr": "^1.5.1",
     "@szhsin/react-menu": "^2.2.0",
@@ -122,6 +128,7 @@
     "date-fns": "^2.24.0",
     "diff-arrays-of-objects": "^1.1.8",
     "dropzone": "^5.9.3",
+    "html-loader": "^3.1.0",
     "html2canvas": "^1.0.0-rc.7",
     "immutability-helper": "^3.0.0",
     "imports-loader": "^2.0.0",
@@ -155,6 +162,8 @@
     "react-dom": "^17.0.1",
     "react-draggable": "^4.4.4",
     "react-rnd": "^10.3.5",
+    "react-fontawesome": "^1.7.1",
+    "react-router-dom": "^6.2.2",
     "react-select": "^4.2.1",
     "react-table": "^7.6.3",
     "react-timer-hook": "^3.0.5",
diff --git a/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js b/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
index dd9874976..d1ee8b3b3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/casts/static/js/cast.js
@@ -68,25 +68,6 @@ define('pgadmin.node.cast', [
 
       },
 
-      // Define the backform model for cast node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Define the schema for cast
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          editable: false, type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode: ['properties'],
-        },
-        {
-          id: 'description', label: gettext('Comment'),
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        },
-        ],
-      }),
-
       getSchema: function(treeNodeInfo, itemNodeData){
         return new CastSchema({
           getTypeOptions: ()=>getNodeAjaxOptions('get_type', this, treeNodeInfo, itemNodeData),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
index c6d7a7e51..5e830af87 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/static/js/event_trigger.js
@@ -12,9 +12,8 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../static/
 
 define('pgadmin.node.event_trigger', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for event trigger collection
   if (!pgBrowser.Nodes['coll-event_trigger']) {
@@ -80,132 +79,6 @@ define('pgadmin.node.event_trigger', [
           }
         );
       },
-      // Define the model for event trigger node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          oid: undefined,
-          name: undefined,
-          eventowner: undefined,
-          is_sys_obj: undefined,
-          comment: undefined,
-          enabled: 'O',
-          eventfuncoid: undefined,
-          eventfunname: undefined,
-          eventname: 'DDL_COMMAND_START',
-          when: undefined,
-          xmin: undefined,
-          source: undefined,
-          language: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'eventowner': userInfo.name}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the event trigger node
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'eventowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'edit','create'], node: 'role',
-          control: Backform.NodeListByNameControl,
-        },{
-          id: 'is_sys_obj', label: gettext('System event trigger?'),
-          cell:'boolean', type: 'switch',
-          mode: ['properties'],
-        },{
-          id: 'comment', label: gettext('Comment'), type: 'multiline',
-        },{
-          id: 'enabled', label: gettext('Trigger enabled?'),
-          group: gettext('Definition'), mode: ['properties', 'edit','create'],
-          options: [
-            {label: gettext('Enable'), value: 'O'},
-            {label: gettext('Disable'), value: 'D'},
-            {label: gettext('Replica'), value: 'R'},
-            {label: gettext('Always'), value: 'A'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'eventfunname', label: gettext('Trigger function'),
-          type: 'text', control: 'node-ajax-options', group: gettext('Definition'),
-          url:'fopts', cache_node: 'trigger_function',
-        },{
-          id: 'eventname', label: gettext('Event'),
-          group: gettext('Definition'), cell: 'string',
-          options: [
-            {label: gettext('DDL COMMAND START'), value: 'DDL_COMMAND_START'},
-            {label: gettext('DDL COMMAND END'), value: 'DDL_COMMAND_END'},
-            {label: gettext('SQL DROP'), value: 'SQL_DROP'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'when', label: gettext('When TAG in'),  cell: 'string',
-          type: 'text', group: gettext('Definition'),
-          control: Backform.SqlFieldControl,
-          extraClasses:['custom_height_css_class'],
-        },{
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
-          group: gettext('Security'), mode: ['edit', 'create'],
-          min_version: 90200, canAdd: true,
-          canEdit: false, canDelete: true, control: 'unique-col-collection',
-        },
-        ],
-        // event trigger model data validation.
-        validate: function() {
-          var msg = undefined;
-          // Clear any existing error msg.
-          this.errorModel.clear();
-
-          if (_.isUndefined(this.get('name'))
-              || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventowner'))
-              || String(this.get('eventowner')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger owner cannot be empty.');
-            this.errorModel.set('eventowner', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('enabled'))) {
-            msg = gettext('Event trigger enabled status cannot be empty.');
-            this.errorModel.set('enabled', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventfunname'))
-              || String(this.get('eventfunname')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Event trigger function cannot be empty.');
-            this.errorModel.set('eventfunname', msg);
-            return msg;
-          }
-
-          if (_.isUndefined(this.get('eventname'))) {
-            msg = gettext('Event trigger event cannot be empty.');
-            this.errorModel.set('eventname', msg);
-            return msg;
-          }
-
-          return null;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
index 6045b0c75..82001e107 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
@@ -13,9 +13,8 @@ import ExtensionsSchema from './extension.ui';
 
 define('pgadmin.node.extension', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser',
-  'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   /*
    * Create and Add an Extension Collection into nodes
@@ -96,109 +95,6 @@ define('pgadmin.node.extension', [
        * Define model for the Node and specify the properties
        * of the model in schema.
        */
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [
-          {
-            id: 'name', label: gettext('Name'), first_empty: true,
-            type: 'text', mode: ['properties', 'create', 'edit'],
-            visible: true, url:'avails', readonly: function(m) {
-              return !m.isNew();
-            },
-            transform: function(data, cell) {
-              var res = [],
-                control = cell || this,
-                label = control.model.get('name');
-
-              if (!control.model.isNew()) {
-                res.push({label: label, value: label});
-              }
-              else {
-                if (data && _.isArray(data)) {
-                  _.each(data, function(d) {
-                    if (d.installed_version === null)
-
-                      /*
-                       * d contains json data and sets into
-                       * select's option control
-                       *
-                       * We need to stringify data because formatter will
-                       * convert Array Object as [Object] string
-                       */
-                      res.push({label: d.name, value: JSON.stringify(d)});
-                  });
-                }
-              }
-              return res;
-            },
-
-            /*
-             * extends NodeAjaxOptionsControl to override the properties
-             * getValueFromDOM which takes stringified data from option of
-             * select control and parse it. And `onChange` takes the stringified
-             * data from select's option, thus convert it to json format and set the
-             * data into Model which is used to enable/disable the schema field.
-             */
-            control: Backform.NodeAjaxOptionsControl.extend({
-              getValueFromDOM: function() {
-                var data = this.formatter.toRaw(
-                  _.unescape(this.$el.find('select').val()), this.model);
-                /*
-                 * return null if data is empty to prevent it from
-                 * throwing parsing error. Adds check as name can be empty
-                 */
-                if (data === '') {
-                  return null;
-                }
-                else if (typeof(data) === 'string') {
-                  data=JSON.parse(data);
-                }
-                return data.name;
-              },
-
-              /*
-               * When name is changed, extract value from its select option and
-               * set attributes values into the model
-               */
-              onChange: function() {
-                Backform.NodeAjaxOptionsControl.prototype.onChange.apply(
-                  this, arguments
-                );
-                var selectedValue = this.$el.find('select').val();
-                if (selectedValue.trim() != '') {
-                  var d = this.formatter.toRaw(selectedValue, this.model);
-                  if(typeof(d) === 'string')
-                    d=JSON.parse(d);
-                  this.model.set({
-                    'version' : '',
-                    'relocatable': (
-                      (!_.isNull(d.relocatable[0]) &&
-                        !_.isUndefined(d.relocatable[0])) ? d.relocatable[0]: ''
-                    ),
-                  });
-                } else {
-                  this.model.set({
-                    'version': '', 'relocatable': true, 'schema': '',
-                  });
-                }
-              },
-            }),
-          },
-          {
-            id: 'oid', label: gettext('OID'), cell: 'string',
-            type: 'text', mode: ['properties'],
-          },
-          {
-            id: 'owner', label: gettext('Owner'), control: 'node-list-by-name',
-            mode: ['properties'], node: 'role', cell: 'string',
-            cache_level: 'server',
-          },
-          {
-            id: 'comment', label: gettext('Comment'), cell: 'string',
-            type: 'multiline', readonly: true,
-          },
-        ],
-      }),
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['extension'];
         return new ExtensionsSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
index 8f0ed95ef..4dc85aae0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server.js
@@ -13,9 +13,9 @@ import ForeignServerSchema from './foreign_server.ui';
 
 define('pgadmin.node.foreign_server', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/pgadmin',
-  'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
+  'pgadmin.browser', 'pgadmin.browser.collection',
   'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for foreign server collection
   if (!pgBrowser.Nodes['coll-foreign_server']) {
@@ -82,45 +82,6 @@ define('pgadmin.node.foreign_server', [
           }
         );
       },
-
-      // Defining model for foreign server node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'fsrvowner': userInfo.name}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Defining schema for the foreign server node
-        schema: [
-          {
-            id: 'name', label: gettext('Name'), cell: 'string',
-            type: 'text', disabled: function() {
-              return (
-                this.mode == 'edit' && this.node_info.server.version < 90200
-              );
-            },
-          }, {
-            id: 'oid', label: gettext('OID'), cell: 'string',
-            type: 'text', mode: ['properties'],
-          }, {
-            id: 'fsrvowner', label: gettext('Owner'), type: 'text',
-            control: Backform.NodeListByNameControl, node: 'role',
-            mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
-          }, {
-            id: 'description', label: gettext('Comment'), cell: 'string',
-            type: 'multiline',
-          },
-        ],
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
index 5c5be3c85..b45be8187 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper.js
@@ -12,10 +12,10 @@ import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
 import ForeignDataWrapperSchema from './foreign_data_wrapper.ui';
 
 define('pgadmin.node.foreign_data_wrapper', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/gettext', 'sources/url_for', 'jquery',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for foreign data wrapper collection
   if (!pgBrowser.Nodes['coll-foreign_data_wrapper']) {
@@ -87,44 +87,6 @@ define('pgadmin.node.foreign_data_wrapper', [
           }
         );
       },
-
-      // Defining model for foreign data wrapper node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'fdwowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Defining schema for the foreign data wrapper node
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: function() {
-            // name field will be disabled only if edit mode
-            return (
-              this.mode == 'edit'
-            );
-          },
-        }, {
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        }, {
-          id: 'fdwowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'create', 'properties'], select2: { allowClear: false },
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
index aaabe734d..56dc670a1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/languages/static/js/language.js
@@ -10,13 +10,12 @@
 import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../static/js/node_ajax';
 import LanguageSchema from './language.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../static/js/privilege.ui';
-import _ from 'lodash';
 
 define('pgadmin.node.language', [
   'sources/gettext', 'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for languages collection
   if (!pgBrowser.Nodes['coll-language']) {
@@ -71,37 +70,6 @@ define('pgadmin.node.language', [
         }]);
       },
 
-      // Define the model for language node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'lanowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the language node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },{
-          id: 'lanowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false },
-        },
-        {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        },
-        ],
-      }),
 
       getSchema: function(treeNodeInfo, itemNodeData){
         return new LanguageSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
index b767057cd..697ddf265 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
@@ -12,9 +12,9 @@ import PublicationSchema from './publication.ui';
 
 define('pgadmin.node.publication', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'sources/pgadmin', 'pgadmin.browser',
   'pgadmin.browser.collection', 'pgadmin.browser.server.privilege',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform) {
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for publications collection
   if (!pgBrowser.Nodes['coll-publication']) {
@@ -23,7 +23,7 @@ define('pgadmin.node.publication', [
         node: 'publication',
         label: gettext('Publications'),
         type: 'coll-publication',
-        columns: ['name', 'pubowner', 'pubtable', 'all_table'],
+        columns: ['name', 'pubowner', 'proptable', 'all_table'],
 
       });
   }
@@ -70,82 +70,7 @@ define('pgadmin.node.publication', [
           icon: 'wcTabIcon icon-publication', data: {action: 'create'},
         }]);
       },
-      // Define the model for publication node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
 
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'pubowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the publication node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-          visible: function() {
-            if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
-              && !_.isUndefined(this.node_info.server.version) &&
-                this.node_info.server.version >= 100000) {
-              return true;
-            }
-            return false;
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },{
-          id: 'pubowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          disabled: function(m){
-            if(m.isNew())
-              return true;
-            return false;
-          },
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
-        },{
-          id: 'all_table', label: gettext('All tables?'), type: 'switch',
-          group: gettext('Definition'), mode: ['edit', 'properties', 'create'], deps: ['name'],
-          readonly: function(m) {return !m.isNew();},
-        },
-        {
-          id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
-          mode: ['properties'],
-        },
-        ],
-
-
-        /* validate function is used to validate the input given by
-         * the user. In case of error, message will be displayed on
-         * the GUI for the respective control.
-         */
-
-        sessChanged: function() {
-          if (this.sessAttrs['pubtable'] == '' && this.origSessAttrs['pubtable'] == '')
-            return false;
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-
-        canCreate: function(itemData, item) {
-
-          var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
-            server = treeData['server'];
-
-          // If server is less than 10 then do not allow 'create' menu
-          if (server && server.version < 100000)
-            return false;
-
-          // by default we want to allow create menu
-          return true;
-        },
-
-      }),
 
       getSchema: function(treeNodeInfo, itemNodeData){
         return new PublicationSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
index 46cfb0e87..55736d4b0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
@@ -147,7 +147,7 @@ export default class PublicationSchema extends BaseUISchema {
       group: gettext('Definition'), mode: ['edit', 'create'],
       deps: ['all_table'], disabled: obj.isAllTable,
     },{
-      id: 'pubtable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
+      id: 'proptable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
       mode: ['properties'],
     },{
       type: 'nested-fieldset', mode: ['create','edit', 'properties'],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
index 58eac45a8..668b4eba5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_tables.sql
@@ -1,3 +1,6 @@
 SELECT pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
-AS pubtable  FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
+AS pubtable,
+pg_catalog.quote_ident(pgb_table.schemaname)||'.'||pg_catalog.quote_ident(pgb_table.tablename)
+AS proptable
+  FROM pg_catalog.pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
 AND pgb_table.schemaname NOT LIKE 'pgagent';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
index 25c0f04fc..df8d9b4f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/aggregates/static/js/aggregate.js
@@ -45,37 +45,6 @@ define('pgadmin.node.aggregate', [
 
         this.initialized = true;
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Aggregate'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }
-        ],
-      }),
       getSchema: ()=>{
         return new AggregateSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
index 8785d147a..e1152eb22 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/js/catalog_object_column.js
@@ -45,32 +45,6 @@ define('pgadmin.node.catalog_object_column', [
         getSchema: function() {
           return new CatalogObjectColumnSchema();
         },
-        model: pgAdmin.Browser.Node.Model.extend({
-          defaults: {
-            attname: undefined,
-            attowner: undefined,
-            atttypid: undefined,
-            attnum: undefined,
-            cltype: undefined,
-            collspcname: undefined,
-            attacl: undefined,
-            is_sys_obj: undefined,
-            description: undefined,
-          },
-          schema: [{
-            id: 'attname', label: gettext('Column'), cell: 'string',
-            type: 'text', readonly: true,
-          },{
-            id: 'attnum', label: gettext('Position'), cell: 'string',
-            type: 'text', readonly: true,
-          },{
-            id: 'cltype', label: gettext('Data type'), cell: 'string',
-            group: gettext('Definition'), type: 'text', readonly: true,
-          },{
-            id: 'description', label: gettext('Comment'), cell: 'string',
-            type: 'multiline', readonly: true,
-          }],
-        }),
       });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
index 06753a427..dac46721a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/js/catalog_object.js
@@ -43,31 +43,6 @@ define('pgadmin.node.catalog_object', [
 
       },
       getSchema: ()=>new CatalogObjectSchema(),
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgAdmin.Browser.Node.Model.extend({
-        defaults: {
-          name: undefined,
-          namespaceowner: undefined,
-          nspacl: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline' ,  readonly: true,
-        },
-        ],
-      }),
 
     });
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
index 586f410bc..4d3dff132 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.js
@@ -69,42 +69,6 @@ define('pgadmin.node.collation', [
         ]);
 
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema', control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }
-        ],
-      }),
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['collation'];
         return new CollationSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
index 67f23e5ca..4c6594ddb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/domain_constraints/static/js/domain_constraints.js
@@ -75,43 +75,6 @@ define('pgadmin.node.domain_constraints', [
       getSchema: function() {
         return new DomainConstraintSchema();
       },
-
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        // Domain Constraint Schema
-        schema: [{
-          id: 'name', label: gettext('Name'), type:'text', cell:'string',
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline', cell:
-          'string', mode: ['properties', 'create', 'edit'], min_version: 90500,
-        }],
-        // Client Side Validation
-        validate: function() {
-          var err = {},
-            errmsg;
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('consrc')) || String(this.get('consrc')).replace(/^\s+|\s+$/g, '') == '') {
-            err['consrc'] = gettext('Check cannot be empty.');
-            errmsg = errmsg || err['consrc'];
-
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
index a14fbf395..8b2b361f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/static/js/domain.js
@@ -98,38 +98,6 @@ define('pgadmin.node.domain', [
           }
         );
       },
-
-      // Domain Node Model
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema = args.node_info.schema.label;
-            this.set({'basensp': schema}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'owner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        // Domain Schema
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string', control: Backform.NodeListByNameControl,
-          node: 'role',  type: 'text', mode: ['edit', 'create', 'properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
index 8e6059486..3affdeefb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.js
@@ -10,15 +10,16 @@ import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../stat
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import ForeignTableSchema from './foreign_table.ui';
+import _ from 'lodash';
 
 /* Create and Register Foreign Table Collection and Node. */
 define('pgadmin.node.foreign_table', [
-  'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.backgrid',
+  'sources/gettext', 'sources/url_for', 'jquery', 'backbone',
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backgrid',
   'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node',
   'pgadmin.browser.collection',
 ], function(
-  gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser, Backform, Backgrid,
+  gettext, url_for, $, Backbone, pgAdmin, pgBrowser, Backgrid,
   schemaChild, schemaChildTreeNode
 ) {
 
@@ -34,465 +35,6 @@ define('pgadmin.node.foreign_table', [
       });
   }
 
-  // Options Model
-  var ColumnOptionsModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'option',
-    defaults: {
-      option: undefined,
-      value: undefined,
-    },
-    schema: [
-      {id: 'option', label: gettext('Option'), type:'text', editable: true, cellHeaderClasses: 'width_percent_30'},
-      {
-        id: 'value', label: gettext('Value'), type: 'text', editable: true, cellHeaderClasses: 'width_percent_50',
-      },
-    ],
-    validate: function() {
-      if (_.isUndefined(this.get('value')) ||
-          _.isNull(this.get('value')) ||
-          String(this.get('value')).replace(/^\s+|\s+$/g, '') == '') {
-        var msg = 'Please enter a value.';
-
-        this.errorModel.set('value', msg);
-
-        return msg;
-      } else {
-        this.errorModel.unset('value');
-      }
-
-      return null;
-    },
-  });
-
-  // Columns Model
-  var ColumnsModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'attnum',
-    defaults: {
-      attname: undefined,
-      datatype: undefined,
-      typlen: undefined,
-      precision: undefined,
-      typdefault: undefined,
-      attnotnull: undefined,
-      collname: undefined,
-      attnum: undefined,
-      inheritedfrom: undefined,
-      inheritedid: undefined,
-      attstattarget: undefined,
-      coloptions: [],
-    },
-    type_options: undefined,
-    schema: [{
-      id: 'attname', label: gettext('Name'), cell: 'string', type: 'text',
-      editable: 'is_editable_column', cellHeaderClasses: 'width_percent_40',
-    },{
-      id: 'datatype', label: gettext('Data type'), cell: 'node-ajax-options',
-      control: 'node-ajax-options', type: 'text', url: 'get_types',
-      editable: 'is_editable_column', cellHeaderClasses: 'width_percent_0',
-      group: gettext('Definition'),
-      transform: function(d, self){
-        self.model.type_options = d;
-        return d;
-      },
-    },
-    {
-      id: 'typlen', label: gettext('Length'),
-      cell: 'string', group: gettext('Definition'),
-      type: 'int', deps: ['datatype'],
-      disabled: function(m) {
-        var val = m.get('typlen');
-        // We will store type from selected from combobox
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) {
-
-          if (!_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('typlen', undefined);
-            }, 10);
-          }
-          return true;
-        }
-
-        var of_type = m.get('datatype'),
-          has_length = false;
-        if(m.type_options) {
-          m.set('is_tlength', false, {silent: true});
-
-          // iterating over all the types
-          _.each(m.type_options, function(o) {
-            // if type from selected from combobox matches in options
-            if ( of_type == o.value ) {
-              // if length is allowed for selected type
-              if(o.length)
-              {
-                // set the values in model
-                has_length = true;
-                m.set('is_tlength', true, {silent: true});
-                m.set('min_val', o.min_val, {silent: true});
-                m.set('max_val', o.max_val, {silent: true});
-              }
-            }
-          });
-
-          if (!has_length && !_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('typlen', undefined);
-            }, 10);
-          }
-
-          return !(m.get('is_tlength'));
-        }
-        if (!has_length && !_.isUndefined(val)) {
-          setTimeout(function() {
-            m.set('typlen', undefined);
-          }, 10);
-        }
-        return true;
-      },
-      cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'precision', label: gettext('Precision'),
-      type: 'int', deps: ['datatype'],
-      cell: 'string', group: gettext('Definition'),
-      disabled: function(m) {
-        var val = m.get('precision');
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) {
-
-          if (!_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('precision', undefined);
-            }, 10);
-          }
-          return true;
-        }
-
-        var of_type = m.get('datatype'),
-          has_precision = false;
-
-        if(m.type_options) {
-          m.set('is_precision', false, {silent: true});
-          // iterating over all the types
-          _.each(m.type_options, function(o) {
-            // if type from selected from combobox matches in options
-            if ( of_type == o.value ) {
-              // if precession is allowed for selected type
-              if(o.precision)
-              {
-                has_precision = true;
-                // set the values in model
-                m.set('is_precision', true, {silent: true});
-                m.set('min_val', o.min_val, {silent: true});
-                m.set('max_val', o.max_val, {silent: true});
-              }
-            }
-          });
-          if (!has_precision && !_.isUndefined(val)) {
-            setTimeout(function() {
-              m.set('precision', undefined);
-            }, 10);
-          }
-          return !(m.get('is_precision'));
-        }
-        if (!has_precision && !_.isUndefined(val)) {
-          setTimeout(function() {
-            m.set('precision', undefined);
-          }, 10);
-        }
-        return true;
-      }, cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'typdefault', label: gettext('Default'), type: 'text',
-      cell: 'string', min_version: 90300, group: gettext('Definition'),
-      placeholder: gettext('Enter an expression or a value.'),
-      cellHeaderClasses: 'width_percent_10',
-      editable: function(m) {
-        if(!(_.isUndefined(m.get('inheritedid'))
-            || _.isNull(m.get('inheritedid'))
-            || _.isUndefined(m.get('inheritedfrom'))
-            || _.isNull(m.get('inheritedfrom')))) { return false; }
-        if (this.get('node_info').server.version < 90300){
-          return false;
-        }
-        return true;
-      },
-    },
-    {
-      id: 'attnotnull', label: gettext('Not NULL?'),
-      cell: 'boolean',type: 'switch', editable: 'is_editable_column',
-      cellHeaderClasses: 'width_percent_10', group: gettext('Definition'),
-    },
-    {
-      id: 'attstattarget', label: gettext('Statistics'), min_version: 90200,
-      cell: 'integer', type: 'int', group: gettext('Definition'),
-      editable: function(m) {
-        if (_.isUndefined(m.isNew) || m.isNew()) { return false; }
-        if (this.get('node_info').server.version < 90200){
-          return false;
-        }
-        return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-          || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-      }, cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'collname', label: gettext('Collation'), cell: 'node-ajax-options',
-      control: 'node-ajax-options', type: 'text', url: 'get_collations',
-      min_version: 90300, editable: function(m) {
-        if (!(_.isUndefined(m.isNew)) && !m.isNew()) { return false; }
-        return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-           || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-      },
-      cellHeaderClasses: 'width_percent_20', group: gettext('Definition'),
-    },
-    {
-      id: 'attnum', cell: 'string',type: 'text', visible: false,
-    },
-    {
-      id: 'inheritedfrom', label: gettext('Inherited From'), cell: 'string',
-      type: 'text', visible: false, mode: ['properties', 'edit'],
-      cellHeaderClasses: 'width_percent_10',
-    },
-    {
-      id: 'coloptions', label: gettext('Options'), cell: 'string',
-      type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
-      model: ColumnOptionsModel, canAdd: true, canDelete: true, canEdit: false,
-      control: Backform.UniqueColCollectionControl, uniqueCol : ['option'],
-      min_version: 90200,
-    }],
-    validate: function() {
-      var errmsg = null;
-
-      if (_.isUndefined(this.get('attname')) || String(this.get('attname')).replace(/^\s+|\s+$/g, '') == '') {
-        errmsg = gettext('Column Name cannot be empty.');
-        this.errorModel.set('attname', errmsg);
-      } else {
-        this.errorModel.unset('attname');
-      }
-
-      if (_.isUndefined(this.get('datatype')) || String(this.get('datatype'))
-        .replace(/^\s+|\s+$/g, '') == '') {
-        errmsg = gettext('Column Datatype cannot be empty.');
-        this.errorModel.set('datatype', errmsg);
-      } else {
-        this.errorModel.unset('datatype');
-      }
-
-      return errmsg;
-    },
-    is_editable_column: function(m) {
-      return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-       || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
-  /* NodeAjaxOptionsMultipleControl is for multiple selection of Combobox.
-  *  This control is used to select Multiple Parent Tables to be inherited.
-  *  It also populates/vacates Columns on selection/deselection of the option (i.e. table name).
-  *  To populates the column, it calls the server and fetch the columns data
-  *  for the selected table.
-  */
-  var NodeAjaxOptionsMultipleControl = Backform.NodeAjaxOptionsControl.extend({
-    onChange: function() {
-      var model = this.model,
-        attrArr = this.field.get('name').split('.'),
-        name = attrArr.shift(),
-        path = attrArr.join('.'),
-        value = this.getValueFromDOM(),
-        changes = {},
-        columns = model.get('columns'),
-        inherits = model.get(name);
-
-      if (this.model.errorModel instanceof Backbone.Model) {
-        if (_.isEmpty(path)) {
-          this.model.errorModel.unset(name);
-        } else {
-          var nestedError = this.model.errorModel.get(name);
-          if (nestedError) {
-            this.keyPathSetter(nestedError, path, null);
-            this.model.errorModel.set(name, nestedError);
-          }
-        }
-      }
-
-      var self = this;
-
-      if (typeof(inherits)  == 'string'){ inherits = JSON.parse(inherits); }
-
-      // Remove Columns if inherit option is deselected from the combobox
-      if(_.size(value) < _.size(inherits)) {
-        var dif =  _.difference(inherits, value);
-        var rmv_columns = columns.where({inheritedid: parseInt(dif[0])});
-        columns.remove(rmv_columns);
-      }
-      else
-      {
-        _.each(value, function(i) {
-          // Fetch Columns from server
-          var fnd_columns = columns.where({inheritedid: parseInt(i)});
-          if (fnd_columns && fnd_columns.length <= 0) {
-            var inhted_columns = self.fetchColumns(i);
-            columns.add(inhted_columns);
-          }
-        });
-      }
-
-      changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
-      this.stopListening(this.model, 'change:' + name, this.render);
-      model.set(changes);
-      this.listenTo(this.model, 'change:' + name, this.render);
-    },
-    fetchColumns: function(table_id){
-      var self = this,
-        url = 'get_columns',
-        m = self.model.top || self.model;
-
-      var node = this.field.get('schema_node'),
-        node_info = this.field.get('node_info'),
-        full_url = node.generate_url.apply(
-          node, [
-            null, url, this.field.get('node_data'),
-            this.field.get('url_with_id') || false, node_info,
-          ]),
-        cache_level = this.field.get('cache_level') || node.type,
-        cache_node = this.field.get('cache_node');
-
-      cache_node = (cache_node && pgBrowser.Nodes['cache_node']) || node;
-
-      m.trigger('pgadmin:view:fetching', m, self.field);
-      var data = {attrelid: table_id};
-
-      // Fetching Columns data for the selected table.
-      $.ajax({
-        async: false,
-        url: full_url,
-        data: data,
-      })
-        .done(function(res) {
-        /*
-         * We will cache this data for short period of time for avoiding
-         * same calls.
-         */
-          data = cache_node.cache(url, node_info, cache_level, res.data);
-
-        })
-        .fail(function() {
-          m.trigger('pgadmin:view:fetch:error', m, self.field);
-        });
-      m.trigger('pgadmin:view:fetched', m, self.field);
-
-      // To fetch only options from cache, we do not need time from 'at'
-      // attribute but only options.
-      //
-      // It is feasible that the data may not have been fetched.
-      data = (data && data.data) || [];
-      return data;
-
-    },
-  });
-
-
-  // Constraints Model
-  var ConstraintModel = pgBrowser.Node.Model.extend({
-    idAttribute: 'conoid',
-    initialize: function(attrs) {
-      var isNew = (_.size(attrs) === 0);
-      if (!isNew) {
-        this.convalidated_default = this.get('convalidated');
-      }
-      pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-    },
-    defaults: {
-      conoid: undefined,
-      conname: undefined,
-      consrc: undefined,
-      connoinherit: undefined,
-      convalidated: true,
-      conislocal: undefined,
-    },
-    convalidated_default: true,
-    schema: [{
-      id: 'conoid', type: 'text', cell: 'string', visible: false,
-    },{
-      id: 'conname', label: gettext('Name'), type: 'text', cell: 'string',
-      editable: 'is_editable', cellHeaderClasses: 'width_percent_30',
-    },{
-      id: 'consrc', label: gettext('Check'), type: 'multiline',
-      editable: 'is_editable', cell: Backgrid.Extension.TextareaCell,
-      cellHeaderClasses: 'width_percent_30',
-    },{
-      id: 'connoinherit', label: gettext('No inherit?'), type: 'switch',
-      cell: 'boolean', editable: 'is_editable',
-      cellHeaderClasses: 'width_percent_20',
-    },{
-      id: 'convalidated', label: gettext('Validate?'), type: 'switch',
-      cell: 'boolean', cellHeaderClasses: 'width_percent_20',
-      editable: function(m) {
-        if (_.isUndefined(m.isNew)) { return true; }
-        if (!m.isNew()) {
-          if(m.get('convalidated') && m.convalidated_default) {
-            return false;
-          }
-          return true;
-        }
-        return true;
-      },
-    },
-    ],
-    validate: function() {
-      var err = {},
-        errmsg;
-
-      if (_.isUndefined(this.get('conname')) || String(this.get('conname')).replace(/^\s+|\s+$/g, '') == '') {
-        err['conname'] = gettext('Constraint Name cannot be empty.');
-        errmsg = err['conname'];
-      }
-
-      if (_.isUndefined(this.get('consrc')) || String(this.get('consrc'))
-        .replace(/^\s+|\s+$/g, '') == '') {
-        err['consrc'] = gettext('Constraint Check cannot be empty.');
-        errmsg = errmsg || err['consrc'];
-      }
-
-      this.errorModel.clear().set(err);
-
-      return errmsg;
-    },
-    is_editable: function(m) {
-      return _.isUndefined(m.isNew) ? true : m.isNew();
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
-  // Options Model
-  var OptionsModel = pgBrowser.Node.Model.extend({
-    defaults: {
-      option: undefined,
-      value: undefined,
-    },
-    schema: [{
-      id: 'option', label: gettext('Option'), cell: 'string', type: 'text',
-      editable: true, cellHeaderClasses:'width_percent_50',
-    },{
-      id: 'value', label: gettext('Value'), cell: 'string',type: 'text',
-      editable: true, cellHeaderClasses:'width_percent_50',
-    },
-    ],
-    validate: function() {
-      // TODO: Add validation here
-    },
-    toJSON: Backbone.Model.prototype.toJSON,
-  });
-
-
   if (!pgBrowser.Nodes['foreign_table']) {
     pgBrowser.Nodes['foreign_table'] = schemaChild.SchemaChildNode.extend({
       type: 'foreign_table',
@@ -561,160 +103,6 @@ define('pgadmin.node.foreign_table', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var schema = args.node_info.schema._label,
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            // Set Selected Schema and Current User
-            this.set({
-              'basensp': schema, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          owner: undefined,
-          basensp: undefined,
-          is_sys_obj: undefined,
-          description: undefined,
-          ftsrvname: undefined,
-          strftoptions: undefined,
-          inherits: [],
-          columns: [],
-          constraints: [],
-          ftoptions: [],
-          relacl: [],
-          stracl: [],
-          seclabels: [],
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl,
-          node: 'role',  type: 'text', select2: { allowClear: false },
-        },{
-          id: 'basensp', label: gettext('Schema'), cell: 'node-list-by-name',
-          control: 'node-list-by-name', cache_level: 'database', type: 'text',
-          node: 'schema', mode:['create', 'edit'],
-        },{
-          id: 'is_sys_obj', label: gettext('System foreign table?'),
-          cell:'boolean', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        },{
-          id: 'ftsrvname', label: gettext('Foreign server'), cell: 'string', control: 'node-ajax-options',
-          type: 'text', group: gettext('Definition'), url: 'get_foreign_servers',
-          readonly: function(m) { return !m.isNew(); }, cache_node: 'database',
-        },{
-          id: 'inherits', label: gettext('Inherits'), group: gettext('Definition'),
-          type: 'array', min_version: 90500, control: NodeAjaxOptionsMultipleControl,
-          url: 'get_tables', select2: {multiple: true},
-          'cache_level': 'database',
-          transform: function(d) {
-            if (this.field.get('mode') == 'edit') {
-              var oid = this.model.get('oid');
-              var s = _.findWhere(d, {'id': oid});
-              if (s) {
-                d = _.reject(d, s);
-              }
-            }
-            return d;
-          },
-        },{
-          id: 'columns', label: gettext('Columns'), cell: 'string',
-          type: 'collection', group: gettext('Columns'), mode: ['edit', 'create'],
-          model: ColumnsModel, canAdd: true, canDelete: true, canEdit: true,
-          columns: ['attname', 'datatype', 'inheritedfrom'],
-          canDeleteRow: function(m) {
-            return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-              || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-          },
-          canEditRow: function(m) {
-            return (_.isUndefined(m.get('inheritedid')) || _.isNull(m.get('inheritedid'))
-              || _.isUndefined(m.get('inheritedfrom')) || _.isNull(m.get('inheritedfrom'))) ? true : false;
-          },
-        },
-        {
-          id: 'constraints', label: gettext('Constraints'), cell: 'string',
-          type: 'collection', group: gettext('Constraints'), mode: ['edit', 'create'],
-          model: ConstraintModel, canAdd: true, canDelete: true, columns: ['conname','consrc', 'connoinherit', 'convalidated'],
-          canEdit: function(o) {
-            if (o instanceof Backbone.Model) {
-              if (o instanceof ConstraintModel) {
-                return o.isNew();
-              }
-            }
-            return true;
-          }, min_version: 90500, canDeleteRow: function(m) {
-            return (m.get('conislocal') == true || _.isUndefined(m.get('conislocal'))) ? true : false;
-          },
-        },{
-          id: 'strftoptions', label: gettext('Options'), cell: 'string',
-          type: 'text', group: gettext('Definition'), mode: ['properties'],
-        },{
-          id: 'ftoptions', label: gettext('Options'), cell: 'string',
-          type: 'collection', group: gettext('Options'), mode: ['edit', 'create'],
-          model: OptionsModel, canAdd: true, canDelete: true, canEdit: false,
-          control: 'unique-col-collection', uniqueCol : ['option'],
-        },{
-          id: 'relacl', label: gettext('Privileges'), cell: 'string',
-          type: 'text', group: gettext('Security'),
-          mode: ['properties'], min_version: 90200,
-        }, pgBrowser.SecurityGroupSchema, {
-          id: 'acl', label: gettext('Privileges'), model: pgAdmin
-            .Browser.Node.PrivilegeRoleModel.extend(
-              {privileges: ['a','r','w','x']}), uniqueCol : ['grantee', 'grantor'],
-          editable: false, type: 'collection', group: 'security',
-          mode: ['edit', 'create'],
-          canAdd: true, canDelete: true, control: 'unique-col-collection',
-          min_version: 90200,
-        },{
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, type: 'collection',
-          group: 'security', mode: ['edit', 'create'],
-          min_version: 90100, canAdd: true,
-          canEdit: false, canDelete: true,
-          control: 'unique-col-collection', uniqueCol : ['provider'],
-        },
-        ],
-        validate: function()
-        {
-          var err = {},
-            errmsg = null;
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('basensp')) || String(this.get('basensp'))
-            .replace(/^\s+|\s+$/g, '') == '') {
-            err['basensp'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['basensp'];
-          }
-
-          if (_.isUndefined(this.get('ftsrvname')) || String(this.get('ftsrvname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['ftsrvname'] = gettext('Foreign server cannot be empty.');
-            errmsg = errmsg || err['ftsrvname'];
-          }
-
-          this.errorModel.clear().set(err);
-
-          return errmsg;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
index 0049de5bd..073dd4acc 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.js
@@ -93,32 +93,6 @@ define('pgadmin.node.fts_configuration', [
           }
         );
       },
-
-      // Defining model for FTS Configuration node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        initialize: function(attrs, opts) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-          if (isNew) {
-            var user = pgBrowser.serverInfo[opts.node_info.server._id].user;
-            this.set({
-              'owner': user.name,
-              'schema': opts.node_info.schema._id,
-            }, {silent: true});
-          }
-        },
-        // Defining schema for FTS Configuration
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
index 5d5bd3a8f..0ea741034 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/static/js/fts_dictionary.js
@@ -88,31 +88,6 @@ define('pgadmin.node.fts_dictionary', [
           }
         );
       },
-
-      // Defining backform model for FTS Dictionary node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-          if (isNew) {
-            var user = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'owner': user.name,
-              'schema': args.node_info.schema._id,
-            }, {silent: true});
-          }
-        },
-        // Defining schema for fts dictionary
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
index 27a4ce87f..ad5579d0d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parsers/static/js/fts_parser.js
@@ -70,108 +70,6 @@ define('pgadmin.node.fts_parser', [
 
       },
 
-      // Defining backform model for fts parser node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,          // Fts parser name
-          is_sys_obj: undefined,  // Is system object
-          description: undefined,   // Comment on parser
-        },
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(
-            this, arguments
-          );
-          if (isNew) {
-            this.set('schema', args.node_info.schema._id);
-          }
-        },
-        // Defining schema for fts parser
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode:['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-
-        /*
-         * Triggers control specific error messages for parser name,
-         * start, token, end, lextype functions and schema, if any one of them is not specified
-         * while creating new fts parser
-         */
-        validate: function() {
-          var name = this.get('name'),
-            start = this.get('prsstart'),
-            token = this.get('prstoken'),
-            end = this.get('prsend'),
-            lextype = this.get('prslextype'),
-            schema = this.get('schema'),
-            msg;
-
-          // Validate fts parser name
-          if (_.isUndefined(name) ||
-                _.isNull(name) ||
-                String(name).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name must be specified.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          // Validate start function control
-          else if (_.isUndefined(start) ||
-                    _.isNull(start) ||
-                    String(start).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Start function must be selected.');
-            this.errorModel.set('prsstart', msg);
-            return msg;
-          }
-
-          // Validate gettoken function control
-          else if (_.isUndefined(token) ||
-                    _.isNull(token) ||
-                    String(token).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Get next token function must be selected.');
-            this.errorModel.set('prstoken', msg);
-            return msg;
-          }
-
-          // Validate end function control
-          else if (_.isUndefined(end) ||
-                    _.isNull(end) ||
-                    String(end).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('End function must be selected.');
-            this.errorModel.set('prsend', msg);
-            return msg;
-          }
-
-          // Validate lextype function control
-          else if (_.isUndefined(lextype) ||
-                    _.isNull(lextype) ||
-                    String(lextype).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Lextype function must be selected.');
-            this.errorModel.set('prslextype', msg);
-            return msg;
-          }
-
-          // Validate schema for fts parser
-          else if (_.isUndefined(schema) ||
-                    _.isNull(schema) ||
-                    String(schema).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Schema must be selected.');
-            this.errorModel.set('schema', msg);
-            return msg;
-          }
-          else this.errorModel.clear();
-
-          this.trigger('on-status-clear');
-          return null;
-        },
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['fts_parser'];
         return new FTSParserSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
index 791adb2f9..5320246f3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/static/js/fts_template.js
@@ -70,65 +70,6 @@ define('pgadmin.node.fts_template', [
 
       },
 
-      // Defining backform model for fts template node
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-          if (isNew) {
-            this.set('schema', args.node_info.schema._id);
-          }
-        },
-        // Defining schema for fts template
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', cellHeaderClasses: 'width_percent_50',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode:['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', cellHeaderClasses: 'width_percent_50',
-        }],
-
-        /*
-         * Triggers control specific error messages for template name,
-         * lexize function and schema, if any one of them is not specified
-         * while creating new fts template
-         */
-        validate: function() {
-          var name = this.get('name'),
-            lexize = this.get('tmpllexize'),
-            schema = this.get('schema'),
-            msg;
-
-          // Validate fts template name
-          if (_.isUndefined(name) || _.isNull(name) || String(name).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name must be specified.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-
-          // Validate lexize function control
-          else if (_.isUndefined(lexize) || _.isNull(lexize) || String(lexize).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Lexize function must be selected.');
-            this.errorModel.set('tmpllexize', msg);
-            return msg;
-          }
-
-          // Validate schema for fts template
-          else if (_.isUndefined(schema) || _.isNull(schema) || String(schema).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Schema must be selected.');
-            this.errorModel.set('schema', msg);
-            return msg;
-          }
-          else this.errorModel.clear();
-
-          this.trigger('on-status-clear');
-          return null;
-        },
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['fts_template'];
         return new FTSTemplateSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
index 41171c62a..b9107d98f 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
 import FunctionSchema from './function.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
-import _ from 'lodash';
 
 /* Create and Register Function Collection and Node. */
 define('pgadmin.node.function', [
@@ -109,44 +108,7 @@ define('pgadmin.node.function', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema_id = args.node_info.schema._id;
-            this.set({'pronamespace': schema_id}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'funcowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'isDisabled',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'funcowner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl, node: 'role',  type:
-          'text', disabled: 'isDisabled',
-        },{
-          id: 'pronamespace', label: gettext('Schema'), cell: 'string',
-          control: 'node-list-by-id', type: 'text', cache_level: 'database',
-          node: 'schema', disabled: 'isDisabled', mode: ['create', 'edit'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled',
-        }],
-      }),
     });
-
   }
-
   return pgBrowser.Nodes['function'];
 });
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
index 1b6b61863..7cbcdc907 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js
@@ -11,7 +11,6 @@ import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../
 import FunctionSchema from './function.ui';
 import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
 import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
-import _ from 'lodash';
 
 /* Create and Register Procedure Collection and Node. */
 define('pgadmin.node.procedure', [
@@ -126,126 +125,6 @@ define('pgadmin.node.procedure', [
         );
       },
 
-      model: Function.model.extend({
-        defaults: _.extend({},
-          Function.model.prototype.defaults,
-          {
-            lanname: 'edbspl',
-          }
-        ),
-        canVarAdd: function() {
-          var server = this.node_info.server;
-          return server.version >= 90500;
-        },
-        isVisible: function() {
-          if (this.name == 'sysfunc') { return false; }
-          else if (this.name == 'sysproc') { return true; }
-          return false;
-        },
-        isDisabled: function(m) {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          switch(this.name){
-          case 'provolatile':
-          case 'proisstrict':
-          case 'procost':
-          case 'proleakproof':
-            if(this.node_info.server.version < 90500 ||
-              this.node_info.server.server_type != 'ppas' ||
-              m.get('lanname') != 'edbspl') {
-
-              setTimeout(function() {
-                m.set('provolatile', null);
-                m.set('proisstrict', false);
-                m.set('procost', null);
-                m.set('proleakproof', false);
-              }, 10);
-              return true;
-            }
-            else{
-              return false;
-            }
-          case 'variables':
-          case 'prosecdef':
-            return this.node_info.server.version < 90500;
-          case 'prorows':
-            var server = this.node_info.server;
-            return !(server.version >= 90500 && m.get('proretset') == true);
-          case 'proparallel':
-            if (this.node_info.server.version < 90600 ||
-              this.node_info.server.server_type != 'ppas' ||
-              m.get('lanname') != 'edbspl') {
-              setTimeout(function() {
-                m.set('proparallel', null);
-              }, 10);
-              return true;
-            }
-            else{
-              return false;
-            }
-          case 'lanname':
-            return this.node_info.server.version < 110000;
-          default:
-            return false;
-          }
-        },
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          return null;
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
index ec0b9f2c5..1eed8e8bf 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js
@@ -107,151 +107,6 @@ define('pgadmin.node.trigger_function', [
           }
         );
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            // Set Selected Schema
-            var schema_id = args.node_info.schema._id;
-            this.set({'pronamespace': schema_id}, {silent: true});
-
-            // Set Current User
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'funcowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          funcowner: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'isDisabled', readonly: 'isReadonly',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'funcowner', label: gettext('Owner'), cell: 'string',
-          control: Backform.NodeListByNameControl, node: 'role',  type:
-          'text', disabled: 'isDisabled', readonly: 'isReadonly',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'isDisabled', readonly: 'isReadonly',
-        }],
-        validate: function(keys)
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          // Nothing to validate
-          if(keys && keys.length == 0) {
-            this.errorModel.clear();
-            return null;
-          }
-
-          if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') {
-            err['funcowner'] = gettext('Owner cannot be empty.');
-            errmsg = errmsg || err['funcowner'];
-          }
-
-          if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
-            err['pronamespace'] = gettext('Schema cannot be empty.');
-            errmsg = errmsg || err['pronamespace'];
-          }
-
-          if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') {
-            err['prorettypename'] = gettext('Return type cannot be empty.');
-            errmsg = errmsg || err['prorettypename'];
-          }
-
-          if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['lanname'] = gettext('Language cannot be empty.');
-            errmsg = errmsg || err['lanname'];
-          }
-
-          if (String(this.get('lanname')) == 'c') {
-            if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
-              .replace(/^\s+|\s+$/g, '') == '') {
-              err['probin'] = gettext('Object File cannot be empty.');
-              errmsg = errmsg || err['probin'];
-            }
-
-            if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc_c'] = gettext('Link Symbol cannot be empty.');
-              errmsg = errmsg || err['prosrc_c'];
-            }
-          }
-          else {
-            if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
-              err['prosrc'] = gettext('Code cannot be empty.');
-              errmsg = errmsg || err['prosrc'];
-            }
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-        isVisible: function() {
-          if (this.name == 'sysproc') { return false; }
-          return true;
-        },
-        isReadonly: function(m) {
-          switch(this.name){
-          case 'proargs':
-          case 'proargtypenames':
-          case 'prorettypename':
-          case 'proretset':
-          case 'proiswindow':
-            return !m.isNew();
-          default:
-            return false;
-          }
-        },
-        isDisabled: function(m) {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          if (this.name === 'prorows'){
-            if(m.get('proretset') == true) {
-              return false;
-            }
-            return true;
-          } else {
-            return false;
-          }
-        },
-        canVarAdd: function() {
-          return !(this.node_info &&  'catalog' in this.node_info);
-        },
-      }),
     });
 
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
index 98fff6bab..3a2bb65a8 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
@@ -45,37 +45,6 @@ define('pgadmin.node.operator', [
 
         this.initialized = true;
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'owner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Operator'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          control: 'node-list-by-name',
-          node: 'role',
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }
-        ],
-      }),
       getSchema: ()=>{
         return new OperatorSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
index a3c340407..d9ebb9d3d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/edbvars/static/js/edbvar.js
@@ -48,16 +48,6 @@ define('pgadmin.node.edbvar', [
       },
       canDrop: false,
       canDropCascade: false,
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        }]
-      }),
       getSchema: () => {
         return new EDBVarSchema();
       }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
index a2ce63fc3..003f379bd 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js
@@ -92,41 +92,6 @@ define('pgadmin.node.package', [
         // by default we want to allow create menu
         return true;
       },
-      // Define the model for package node.
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({
-              'owner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        // Define the schema for package node.
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: function(m) {
-            return !m.isNew();
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: true, editable: false, visible: function(m) {
-            return !m.isNew();
-          },
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }]
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         var nodeObj = pgBrowser.Nodes['package'];
         return new PackageSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
index 6c358fd58..0e336682a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/js/sequence.js
@@ -106,41 +106,6 @@ define('pgadmin.node.sequence', [
           }
         );
       },
-
-      // Define the model for sequence node.
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-
-            this.set({'seqowner': userInfo.name}, {silent: true});
-            this.set({'schema': schemaInfo._label}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for sequence node.
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'seqowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
-          control: Backform.NodeListByNameControl,
-        },{
-          id: 'comment', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
index c41cbd5d2..42d182c48 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/catalog.js
@@ -42,25 +42,6 @@ define('pgadmin.node.catalog', [
         this.initialized = true;
 
       },
-      model: pgBrowser.Node.Model.extend({
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'namespaceowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true,
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        }]
-      }),
       getSchema: function(treeNodeInfo) {
         return new CatalogSchema(
           {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
index ee384f629..4822c204d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js
@@ -361,36 +361,6 @@ define('pgadmin.node.schema', [
       can_create_schema: function(node) {
         return pgBrowser.Nodes['database'].is_conn_allow.call(this, node);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'namespaceowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'namespaceowner', label: gettext('Owner'), cell: 'string',
-          type: 'text', control: 'node-list-by-name', node: 'role',
-          select2: { allowClear: false },
-        },{
-          id: 'is_sys_obj', label: gettext('System schema?'),
-          cell: 'switch', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline'
-        }]
-      }),
       getSchema: function(treeNodeInfo, itemNodeData) {
         var schemaObj = pgBrowser.Nodes['schema'];
         return new PGSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
index 8181fdc94..104324cb3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js
@@ -100,54 +100,6 @@ define('pgadmin.node.synonym', [
           }
         );
       },
-
-      model: pgAdmin.Browser.Node.Model.extend({
-        isNew: function() {
-          return !this.fetchFromServer;
-        },
-        idAttribute: 'oid',
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            var schemaInfo = args.node_info.schema;
-            this.set({
-              'owner': userInfo.name,
-              'synobjschema': schemaInfo._label,
-              'schema': schemaInfo._label,
-              'targettype': 'r',
-            }, {silent: true});
-          } else {
-            this.fetchFromServer = true;
-          }
-          pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
-
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema', readonly: function(m) { return !m.isNew(); },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          readonly: true , control: 'node-list-by-name',
-          node: 'role', visible: false,
-        }],
-
-        // We will disable everything if we are under catalog node
-        inSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-      }),
       canCreate: function(itemData, item, data) {
         //If check is false then , we will allow create menu
         if (data && data.check == false)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
index 5e12f159a..4df6c7ae7 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js
@@ -98,36 +98,6 @@ define('pgadmin.node.column', [
       getSchema: function(treeNodeInfo, itemNodeData) {
         return getNodeColumnSchema(treeNodeInfo, itemNodeData, pgBrowser);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'attnum',
-
-        defaults: {
-          name: undefined,
-          attnum: undefined,
-          description: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchemaWithColumnCheck',
-          cellHeaderClasses:'width_percent_30',
-          editable: 'editable_check_for_table',
-        },{
-          id: 'attnum', label: gettext('Position'), cell: 'string',
-          type: 'text', disabled: 'notInSchema', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'notInSchema',
-        }],
-        // We will check if we are under schema node & in 'create' mode
-        notInSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-      }),
       // Below function will enable right click menu for creating column
       canCreate: function(itemData, item, data) {
         // If check is false then , we will allow create menu
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
index 433828373..06b41026a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js
@@ -189,16 +189,6 @@ define('pgadmin.node.compound_trigger', [
         );
       },
 
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text',
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }],
-      }),
       canCreate: function(itemData, item, data) {
         //If check is false then , we will allow create menu
         if (data && data.check == false)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
index d135deae5..df5f0e4cb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js
@@ -43,24 +43,6 @@ define('pgadmin.node.constraints', [
 
         pgBrowser.add_menus([]);
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          comment: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('Oid'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-        }],
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
index 3fb8a6c17..cb1749c08 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js
@@ -92,29 +92,6 @@ define('pgadmin.node.index', [
       },
       canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          nspname: undefined,
-          tabname: undefined,
-          spcname: undefined,
-          amname: 'btree',
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'int', readonly: true, mode: ['properties'],
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }],
-      }),
       // Below function will enable right click menu for creating column
       canCreate: function(itemData, item, data) {
         // If check is false then , we will allow create menu
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
index 7b8b144b9..b360c6b8d 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
@@ -305,49 +305,6 @@ function(
       getSchema: function(treeNodeInfo, itemNodeData) {
         return getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowser);
       },
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          oid: undefined,
-          description: undefined,
-          is_partitioned: false,
-          partition_value: undefined,
-        },
-        // Default values!
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[
-                args.node_info.server._id
-              ].user,
-              schemaInfo = args.node_info.schema;
-
-            this.set({
-              'relowner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'oid', label: gettext('OID'), type: 'text', mode: ['properties'],
-        },{
-          id: 'schema', label: gettext('Schema'), type: 'text', node: 'schema',
-          mode: ['create', 'edit', 'properties'],
-        },{
-          id: 'is_partitioned', label:gettext('Partitioned table?'), cell: 'switch',
-          type: 'switch', mode: ['properties', 'create', 'edit'],
-        },{
-          id: 'partition_value', label:gettext('Partition Scheme'),
-          type: 'text', visible: false,
-        },{
-          id: 'description', label: gettext('Comment'), type: 'multiline',
-          mode: ['properties', 'create', 'edit'],
-        }],
-      }),
       canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       // Check to whether table has disable trigger(s)
       canCreate_with_trigger_enable: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
index acc285e99..d1908a6eb 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js
@@ -88,64 +88,6 @@ define('pgadmin.node.row_security_policy', [
           }
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', readonly: true, cellHeaderClasses: 'width_percent_50',
-          mode: ['properties']
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          editable: false, type: 'text', mode: ['properties'],
-        }],
-        validate: function(keys) {
-          var msg;
-          this.errorModel.clear();
-          // If nothing to validate
-          if (keys && keys.length == 0) {
-            return null;
-          }
-
-          if(_.isUndefined(this.get('name'))
-            || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-          if (!this.isNew() && !_.isNull(this.get('using_orig')) && this.get('using_orig') != '' && String(this.get('using')).replace(/^\s+|\s+$/g, '') == ''){
-            msg = gettext('"USING" can not be empty once the value is set');
-            this.errorModel.set('using', msg);
-            return msg;
-          }
-          if (!this.isNew() && !_.isNull(this.get('withcheck_orig')) && this.get('withcheck_orig') != '' && String(this.get('withcheck')).replace(/^\s+|\s+$/g, '') == ''){
-            msg = gettext('"Withcheck" can not be empty once the value is set');
-            this.errorModel.set('withcheck', msg);
-            return msg;
-          }
-          return null;
-        },
-        disableWithCheck: function(m){
-          var event = m.get('event');
-          if ((event == 'SELECT') || (event == 'DELETE')){
-            m.set('withcheck', '');
-            return true;
-          }
-          return false;
-        },
-
-        disableUsing: function(m){
-          var event = m.get('event');
-
-          if (event == 'INSERT'){
-            return true;
-          }
-          return false;
-        },
-
-      }),
       canCreate: function(itemData, item) {
 
         var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
index cde25009b..73ebd4183 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js
@@ -207,54 +207,6 @@ define('pgadmin.node.rule', [
           }
         );
       },
-      /**
-        Define model for the rule node and specify the node
-        properties of the model in schema.
-       */
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        schema: [{
-          id: 'name', label: gettext('Name'),
-          type: 'text', disabled: function(m) {
-            // disable name field it it is system rule
-            if (m && m.get('name') == '_RETURN') {
-              return true;
-            }
-            if (m.isNew && m.isNew() || m.node_info && m.node_info.server.version >= 90400) {
-              return false;
-            }
-            return true;
-          },
-        },
-        {
-          id: 'oid', label: gettext('OID'),
-          type: 'text', mode: ['properties'],
-        },
-        {
-          id: 'comment', label: gettext('Comment'), cell: 'string', type: 'multiline',
-        },
-        ],
-        validate: function() {
-
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name');
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') === '')
-          {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }
-          else
-          {
-            this.errorModel.unset('name');
-          }
-          return null;
-        },
-      }),
 
       // Show or hide create rule menu option on parent node
       canCreate: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
index 1e4ecba89..c60ecbc5c 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js
@@ -187,468 +187,6 @@ define('pgadmin.node.trigger', [
           },
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          is_row_trigger: true,
-          fires: 'BEFORE',
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'int', mode: ['properties'],
-        },{
-          id: 'is_enable_trigger', label: gettext('Trigger enabled?'),
-          mode: ['edit', 'properties'], group: gettext('Definition'),
-          disabled: function() {
-            if(this.node_info && ('catalog' in this.node_info || 'view' in this.node_info)) {
-              return true;
-            }
-            return false;
-          },
-          options: [
-            {label: gettext('Enable'), value: 'O'},
-            {label: gettext('Enable Replica'), value: 'R'},
-            {label: gettext('Enable Always'), value: 'A'},
-            {label: gettext('Disable'), value: 'D'},
-          ],
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-        },{
-          id: 'is_row_trigger', label: gettext('Row trigger?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['is_constraint_trigger'],
-          disabled: function(m) {
-            // Disabled if table is a partitioned table.
-            if (!m.isNew())
-              return true;
-
-            if (_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
-              _.has(m.node_info.table, 'is_partitioned') &&
-               m.node_info.table.is_partitioned && m.node_info.server.version < 110000
-            )
-            {
-              setTimeout(function(){
-                m.set('is_row_trigger', false);
-              },10);
-
-              return true;
-            }
-
-            // If constraint trigger is set to True then row trigger will
-            // automatically set to True and becomes disable
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                // change it's model value
-                setTimeout(function() { m.set('is_row_trigger', true); }, 10);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Check if it is row trigger then enabled it.
-              var is_row_trigger = m.get('is_row_trigger');
-              if (!_.isUndefined(is_row_trigger) && m.node_info['server']['server_type'] == 'ppas') {
-                return false;
-              }
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'is_constraint_trigger', label: gettext('Constraint trigger?'),
-          type: 'switch',
-          mode: ['create','edit', 'properties'],
-          group: gettext('Definition'),
-          deps: ['tfunction'],
-          disabled: function(m) {
-            // Disabled if table is a partitioned table.
-            var tfunction = m.get('tfunction');
-            if ((_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
-              _.has(m.node_info.table, 'is_partitioned') &&
-                m.node_info.table.is_partitioned) ||
-                _.indexOf(Object.keys(m.node_info), 'view') != -1 ||
-                (m.node_info.server.server_type === 'ppas' &&
-                !_.isUndefined(tfunction) &&
-                 tfunction === 'Inline EDB-SPL')) {
-              setTimeout(function(){
-                m.set('is_constraint_trigger', false);
-              },10);
-
-              return true;
-            }
-
-            return m.inSchemaWithModelCheck.apply(this, [m]);
-          },
-        },{
-          id: 'tgdeferrable', label: gettext('Deferrable?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['is_constraint_trigger'],
-          disabled: function(m) {
-            // If constraint trigger is set to True then only enable it
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                return false;
-              } else {
-                // If value is already set then reset it to false
-                if(m.get('tgdeferrable')) {
-                  setTimeout(function() { m.set('tgdeferrable', false); }, 10);
-                }
-                return true;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'tginitdeferred', label: gettext('Deferred?'),
-          type: 'switch', group: gettext('Definition'),
-          mode: ['create','edit', 'properties'],
-          deps: ['tgdeferrable', 'is_constraint_trigger'],
-          disabled: function(m) {
-            // If Deferrable is set to True then only enable it
-            var tgdeferrable = m.get('tgdeferrable');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(tgdeferrable) &&
-                tgdeferrable) {
-                return false;
-              } else {
-                // If value is already set then reset it to false
-                if(m.get('tginitdeferred')) {
-                  setTimeout(function() { m.set('tginitdeferred', false); }, 10);
-                }
-                // If constraint trigger is set then do not disable
-                return m.get('is_constraint_trigger') ? false : true;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'tfunction', label: gettext('Trigger function'),
-          type: 'text', disabled: 'inSchemaWithModelCheck',
-          mode: ['create','edit', 'properties'], group: gettext('Definition'),
-          control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema',
-          cache_node: 'trigger_function',
-        },{
-          id: 'tgargs', label: gettext('Arguments'), cell: 'string',
-          group: gettext('Definition'),
-          type: 'text',mode: ['create','edit', 'properties'], deps: ['tfunction'],
-          disabled: function(m) {
-            // We will disable it when EDB PPAS and trigger function is
-            // set to Inline EDB-SPL
-            var tfunction = m.get('tfunction'),
-              server_type = m.node_info['server']['server_type'];
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(server_type === 'ppas' &&
-                !_.isUndefined(tfunction) &&
-                  tfunction === 'Inline EDB-SPL') {
-                // Disable and clear its value
-                m.set('tgargs', undefined);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          id: 'fires', label: gettext('Fires'), deps: ['is_constraint_trigger'],
-          mode: ['create','edit', 'properties'], group: gettext('Events'),
-          options: function(control) {
-            var table_options = [
-                {label: 'BEFORE', value: 'BEFORE'},
-                {label: 'AFTER', value: 'AFTER'}],
-              view_options = [
-                {label: 'BEFORE', value: 'BEFORE'},
-                {label: 'AFTER', value: 'AFTER'},
-                {label: 'INSTEAD OF', value: 'INSTEAD OF'}];
-            // If we are under table then show table specific options
-            if(_.indexOf(Object.keys(control.model.node_info), 'table') != -1) {
-              return table_options;
-            } else {
-              return view_options;
-            }
-          },
-          control: 'select2', select2: { allowClear: false, width: '100%' },
-          disabled: function(m) {
-            if (!m.isNew())
-              return true;
-            // If contraint trigger is set to True then only enable it
-            var is_constraint_trigger = m.get('is_constraint_trigger');
-            if(!m.inSchemaWithModelCheck.apply(this, [m])) {
-              if(!_.isUndefined(is_constraint_trigger) &&
-                is_constraint_trigger === true) {
-                setTimeout(function() { m.set('fires', 'AFTER'); }, 10);
-                return true;
-              } else {
-                return false;
-              }
-            } else {
-              // Check if it is row trigger then enabled it.
-              var fires_ = m.get('fires');
-              if (!_.isUndefined(fires_) && m.node_info['server']['server_type'] == 'ppas') {
-                return false;
-              }
-              // Disable it
-              return true;
-            }
-          },
-        },{
-          type: 'nested', control: 'fieldset', mode: ['create','edit', 'properties'],
-          label: gettext('Events'), group: gettext('Events'), contentClass: 'row',
-          schema:[{
-            id: 'evnt_insert', label: gettext('INSERT'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_insert = m.get('evnt_insert');
-              if (!_.isUndefined(evn_insert) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_update', label: gettext('UPDATE'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_update = m.get('evnt_update');
-              if (!_.isUndefined(evn_update) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_delete', label: gettext('DELETE'),
-            type: 'switch', mode: ['create','edit', 'properties'],
-            group: gettext('Events'),
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var evn_delete = m.get('evnt_delete');
-              if (!_.isUndefined(evn_delete) && m.node_info['server']['server_type'] == 'ppas' && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          },{
-            id: 'evnt_truncate', label: gettext('TRUNCATE'),
-            type: 'switch', group: gettext('Events'),deps: ['is_row_trigger', 'is_constraint_trigger'],
-            extraToggleClasses: 'pg-el-sm-6',
-            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
-            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
-            disabled: function(m) {
-              var is_constraint_trigger = m.get('is_constraint_trigger'),
-                is_row_trigger = m.get('is_row_trigger'),
-                server_type = m.node_info['server']['server_type'];
-              if (is_row_trigger == true){
-                setTimeout(function(){
-                  m.set('evnt_truncate', false);
-                },10);
-                return true;
-              }
-
-              if (server_type === 'ppas' &&
-                  !_.isUndefined(is_constraint_trigger) &&
-                    !_.isUndefined(is_row_trigger) &&
-                    is_constraint_trigger === false && m.isNew())
-                return false;
-              return m.inSchemaWithModelCheck.apply(this, [m]);
-            },
-          }],
-        },{
-          id: 'whenclause', label: gettext('When'),
-          type: 'text', disabled: 'inSchemaWithModelCheck',
-          mode: ['create', 'edit', 'properties'],
-          control: 'sql-field', visible: true, group: gettext('Events'),
-        },{
-          id: 'columns', label: gettext('Columns'), url: 'nodes',
-          control: 'node-list-by-name', cache_node: 'column', type: 'array',
-          select2: {'multiple': true},
-          deps: ['evnt_update'], node: 'column', group: gettext('Events'),
-          disabled: function(m) {
-            if(this.node_info &&  'catalog' in this.node_info) {
-              return true;
-            }
-            //Disable in edit mode
-            if (!m.isNew()) {
-              return true;
-            }
-            // Enable column only if update event is set true
-            var isUpdate = m.get('evnt_update');
-            if(!_.isUndefined(isUpdate) && isUpdate) {
-              return false;
-            }
-            return true;
-          },
-        },{
-          id: 'tgoldtable', label: gettext('Old table'),
-          type: 'text', group: gettext('Transition'),
-          cell: 'string', mode: ['create', 'edit', 'properties'],
-          deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
-          disabled: 'disableTransition',
-        },{
-          id: 'tgnewtable', label: gettext('New table'),
-          type: 'text', group: gettext('Transition'),
-          cell: 'string', mode: ['create', 'edit', 'properties'],
-          deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
-          disabled: 'disableTransition',
-        },{
-          id: 'prosrc', label: gettext('Code'), group: gettext('Code'),
-          type: 'text', mode: ['create', 'edit'], deps: ['tfunction'],
-          tabPanelCodeClass: 'sql-code-control',
-          control: Backform.SqlCodeControl,
-          visible: true,
-          disabled: function(m) {
-            // We will enable it only when EDB PPAS and trigger function is
-            // set to Inline EDB-SPL
-            var tfunction = m.get('tfunction'),
-              server_type = m.node_info['server']['server_type'];
-
-            return (server_type !== 'ppas' ||
-            _.isUndefined(tfunction) ||
-              tfunction !== 'Inline EDB-SPL');
-          },
-        },{
-          id: 'is_sys_trigger', label: gettext('System trigger?'), cell: 'string',
-          type: 'switch', disabled: 'inSchemaWithModelCheck', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }],
-        validate: function(keys) {
-          var msg;
-          this.errorModel.clear();
-
-          // If nothing to validate
-          if (keys && keys.length == 0) {
-            return null;
-          }
-
-          if(_.isUndefined(this.get('name'))
-            || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Name cannot be empty.');
-            this.errorModel.set('name', msg);
-            return msg;
-          }
-          if(_.isUndefined(this.get('tfunction'))
-            || String(this.get('tfunction')).replace(/^\s+|\s+$/g, '') == '') {
-            msg = gettext('Trigger function cannot be empty.');
-            this.errorModel.set('tfunction', msg);
-            return msg;
-          }
-
-          if(!this.get('evnt_truncate') && !this.get('evnt_delete') &&
-            !this.get('evnt_update') && !this.get('evnt_insert')) {
-            msg = gettext('Specify at least one event.');
-            this.errorModel.set('evnt_truncate', ' ');
-            this.errorModel.set('evnt_delete', ' ');
-            this.errorModel.set('evnt_update', ' ');
-            this.errorModel.set('evnt_insert', msg);
-            return msg;
-          }
-
-          if(!_.isUndefined(this.get('tfunction')) &&
-            this.get('tfunction') === 'Inline EDB-SPL' &&
-              (_.isUndefined(this.get('prosrc'))
-                || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == ''))
-          {
-            msg = gettext('Trigger code cannot be empty.');
-            this.errorModel.set('prosrc', msg);
-            return msg;
-          }
-          return null;
-        },
-        // We will check if we are under schema node & in 'create' mode
-        inSchema: function() {
-          if(this.node_info &&  'catalog' in this.node_info) {
-            return true;
-          }
-          return false;
-        },
-        // We will check if we are under schema node & in 'create' mode
-        inSchemaWithModelCheck: function(m) {
-          if(this.node_info &&  'schema' in this.node_info) {
-            // We will disable control if it's in 'edit' mode
-            return !m.isNew();
-          }
-          return true;
-        },
-        // Checks weather to enable/disable control
-        inSchemaWithColumnCheck: function(m) {
-          if(this.node_info &&  'schema' in this.node_info) {
-            // We will disable control if it's system columns
-            // ie: it's position is less then 1
-            if (m.isNew()) {
-              return false;
-            } else {
-              // if we are in edit mode
-              return (_.isUndefined(m.get('attnum')) || m.get('attnum') < 1 );
-            }
-          }
-          return true;
-        },
-        // Disable/Enable Transition tables
-        disableTransition: function(m) {
-          if (!m.isNew())
-            return true;
-          var flag = false,
-            evnt = null,
-            name = this.name,
-            evnt_count = 0;
-
-          // Disable transition tables for view trigger and PG version < 100000
-          if(_.indexOf(Object.keys(m.node_info), 'table') == -1 ||
-            m.node_info.server.version < 100000) return true;
-
-          if (name == 'tgoldtable') evnt = 'evnt_delete';
-          else if (name == 'tgnewtable') evnt = 'evnt_insert';
-
-          if(m.get('evnt_insert')) evnt_count++;
-          if(m.get('evnt_update')) evnt_count++;
-          if(m.get('evnt_delete')) evnt_count++;
-
-
-          // Disable transition tables if
-          //  - It is a constraint trigger
-          //  - Fires other than AFTER
-          //  - More than one events enabled
-          //  - Update event with the column list
-
-          // Disable Old transition table if both UPDATE and DELETE events are disabled
-          // Disable New transition table if both UPDATE and INSERT events are disabled
-          if(!m.get('is_constraint_trigger') && m.get('fires') == 'AFTER' &&
-            (m.get('evnt_update') || m.get(evnt)) && evnt_count == 1) {
-            flag = (m.get('evnt_update') && (_.size(m.get('columns')) >= 1 && m.get('columns')[0] != ''));
-          }
-
-          flag && setTimeout(function() {
-            if(m.get(name)) {
-              m.set(name, null);
-            }
-          },10);
-
-          return flag;
-        },
-      }),
       canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
       // Check to whether trigger is disable ?
       canCreate_with_trigger_enable: function(itemData, item, data) {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
index f0ec287f0..56ef198e1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/static/js/type.js
@@ -74,48 +74,6 @@ define('pgadmin.node.type', [
 
       },
       ext_funcs: undefined,
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          is_sys_type: false,
-          typtype: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user,
-              schemaInfo = args.node_info.schema;
-
-            this.set({
-              'typeowner': userInfo.name, 'schema': schemaInfo._label,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', mode: ['properties', 'create', 'edit'],
-          disabled: 'schemaCheck',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text' , mode: ['properties'],
-        },{
-          id: 'typeowner', label: gettext('Owner'), cell: 'string',
-          control: 'node-list-by-name',
-          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
-          disabled: 'inSchema', select2: {allowClear: false},
-        }, {
-          id: 'description', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', mode: ['properties', 'create', 'edit'],
-          disabled: 'inSchema',
-        }]
-      }),
       getSchema: (treeNodeInfo, itemNodeData) => {
         let nodeObj = pgAdmin.Browser.Nodes['type'];
         return new TypeSchema(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
index 393707c9b..cbfd68667 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js
@@ -146,93 +146,6 @@ define('pgadmin.node.mview', [
           }
         );
       },
-      /**
-        Define model for the view node and specify the
-        properties of the model in schema.
-       */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            // Set Selected Schema and Current User
-            var schemaLabel = args.node_info.schema._label || 'public',
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'schema': schemaLabel, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        defaults: {
-          spcname: undefined,
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'inSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string',
-          control: 'node-list-by-name', select2: { allowClear: false },
-          node: 'role', disabled: 'inSchema',
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline',
-        }],
-        sessChanged: function() {
-          /* If only custom autovacuum option is enabled the check if the options table is also changed. */
-          if(_.size(this.sessAttrs) == 2 && this.sessAttrs['autovacuum_custom'] && this.sessAttrs['toast_autovacuum']) {
-            return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
-          }
-          if(_.size(this.sessAttrs) == 1 && (this.sessAttrs['autovacuum_custom'] || this.sessAttrs['toast_autovacuum'])) {
-            return this.get('vacuum_table').sessChanged() || this.get('vacuum_toast').sessChanged();
-          }
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-        validate: function(keys) {
-
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name'),
-            field_def = this.get('definition');
-
-          if(_.indexOf(keys, 'autovacuum_custom'))
-            if (_.indexOf(keys, 'autovacuum_enabled') != -1 ||
-              _.indexOf(keys, 'toast_autovacuum_enabled') != -1 )
-              return null;
-
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('name');
-          }
-          if (_.isUndefined(field_def) || _.isNull(field_def) ||
-            String(field_def).replace(/^\s+|\s+$/g, '') == '') {
-            err['definition'] = gettext('Please enter view definition.');
-            errmsg = err['definition'];
-            this.errorModel.set('definition', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('definition');
-          }
-          return null;
-        },
-        // We will disable everything if we are under catalog node
-        inSchema: function() {
-          if(this.node_info && 'catalog' in this.node_info)
-          {
-            return true;
-          }
-          return false;
-        },
-
-      }),
 
       refresh_mview: function(args) {
         var input = args || {},
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
index b98ea6c6c..0ba952954 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/view.js
@@ -108,163 +108,6 @@ define('pgadmin.node.view', [
           }
         );
       },
-      /**
-        Define model for the view node and specify the
-        properties of the model in schema.
-      */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        initialize: function(attrs, args) {
-          if (_.size(attrs) === 0) {
-            // Set Selected Schema and, Current User
-            var schemaLabel = args.node_info.schema._label || 'public',
-              userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({
-              'schema': schemaLabel, 'owner': userInfo.name,
-            }, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-        schema: [{
-          id: 'name', label: gettext('Name'), cell: 'string',
-          type: 'text', disabled: 'notInSchema',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string',
-          type: 'text', mode: ['properties'],
-        },{
-          id: 'owner', label: gettext('Owner'), cell: 'string', control: 'node-list-by-name',
-          node: 'role', disabled: 'notInSchema', select2: { allowClear: false },
-        },{
-          id: 'schema', label: gettext('Schema'), cell: 'string', first_empty: false,
-          control: 'node-list-by-name', type: 'text', cache_level: 'database',
-          node: 'schema', disabled: 'notInSchema', mode: ['create', 'edit'],
-          select2: { allowClear: false }, cache_node: 'database',
-        },{
-          id: 'system_view', label: gettext('System view?'), cell: 'string',
-          type: 'switch', mode: ['properties'],
-        },{
-          id: 'acl', label: gettext('Privileges'),
-          mode: ['properties'], type: 'text', group: gettext('Security'),
-        },{
-          id: 'comment', label: gettext('Comment'), cell: 'string',
-          type: 'multiline', disabled: 'notInSchema',
-        },{
-          id: 'security_barrier', label: gettext('Security barrier?'),
-          type: 'switch', min_version: '90200', group: gettext('Definition'),
-          disabled: 'notInSchema',
-        },{
-          id: 'check_option', label: gettext('Check options'),
-          control: 'select2', group: gettext('Definition'), type: 'text',
-          min_version: '90400', mode:['properties', 'create', 'edit'],
-          select2: {
-            // Set select2 option width to 100%
-            allowClear: false,
-          }, disabled: 'notInSchema',
-          options:[{
-            label: gettext('No'), value: 'no',
-          },{
-            label: gettext('Local'), value: 'local',
-          },{
-            label: gettext('Cascaded'), value: 'cascaded',
-          }],
-        },{
-          id: 'definition', label: gettext('Code'), cell: 'string',
-          type: 'text', mode: ['create', 'edit'], group: gettext('Code'),
-          tabPanelCodeClass: 'sql-code-control',
-          disabled: 'notInSchema',
-          control: Backform.SqlCodeControl.extend({
-            onChange: function() {
-              Backform.SqlCodeControl.prototype.onChange.apply(this, arguments);
-
-              if (!this.model || !(
-                this.model.changed &&
-                this.model.node_info.server.server_type == 'pg' &&
-                // No need to check this when creating a view
-                this.model.get('oid') !== undefined
-              ) || !(
-                this.model.origSessAttrs &&
-                this.model.changed.definition != this.model.origSessAttrs.definition
-              )) {
-                this.model.warn_text = undefined;
-                return;
-              }
-
-              let old_def = this.model.origSessAttrs.definition &&
-                this.model.origSessAttrs.definition.replace(
-                  /\s/gi, ''
-                ).split('FROM'),
-                new_def = [];
-
-              if (this.model.changed.definition !== undefined) {
-                new_def = this.model.changed.definition.replace(
-                  /\s/gi, ''
-                ).split('FROM');
-              }
-
-              if ((old_def.length != new_def.length) || (
-                old_def.length > 1 && (
-                  old_def[0] != new_def[0]
-                )
-              )) {
-                this.model.warn_text = gettext(
-                  'Changing the columns in a view requires dropping and re-creating the view. This may fail if other objects are dependent upon this view, or may cause procedural functions to fail if they are not modified to take account of the changes.'
-                ) + '<br><br><b>' + gettext('Do you wish to continue?') +
-                '</b>';
-              } else {
-                this.model.warn_text = undefined;
-              }
-            },
-          }),
-        }, pgBrowser.SecurityGroupSchema, {
-          // Add Privilege Control
-          id: 'datacl', label: gettext('Privileges'), type: 'collection',
-          model: pgBrowser.Node.PrivilegeRoleModel.extend({
-            privileges: ['a', 'r', 'w', 'd', 'D', 'x', 't'],
-          }), uniqueCol : ['grantee'], editable: false, group: 'security',
-          mode: ['edit', 'create'], canAdd: true, canDelete: true,
-          control: 'unique-col-collection', disabled: 'notInSchema',
-        },{
-          // Add Security Labels Control
-          id: 'seclabels', label: gettext('Security labels'),
-          model: pgBrowser.SecLabelModel, editable: false, type: 'collection',
-          canEdit: false, group: 'security', canDelete: true,
-          mode: ['edit', 'create'], canAdd: true, disabled: 'notInSchema',
-          control: 'unique-col-collection', uniqueCol : ['provider'],
-        }],
-        validate: function() {
-          // Triggers specific error messages for fields
-          var err = {},
-            errmsg,
-            field_name = this.get('name'),
-            field_def = this.get('definition');
-          if (_.isUndefined(field_name) || _.isNull(field_name) ||
-            String(field_name).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Please specify name.');
-            errmsg = err['name'];
-            this.errorModel.set('name', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('name');
-          }
-          if (_.isUndefined(field_def) || _.isNull(field_def) ||
-            String(field_def).replace(/^\s+|\s+$/g, '') == '') {
-            err['definition'] = gettext('Please enter view code.');
-            errmsg = err['definition'];
-            this.errorModel.set('definition', errmsg);
-            return errmsg;
-          }else{
-            this.errorModel.unset('definition');
-          }
-          return null;
-        },
-        // We will disable everything if we are under catalog node
-        notInSchema: function() {
-          if(this.node_info && 'catalog' in this.node_info) {
-            return true;
-          }
-          return false;
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
index 344abcac5..a60fc26d9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js
@@ -351,45 +351,6 @@ define('pgadmin.node.database', [
           }
         );
       },
-      /* Few fields are kept since the properties tab for collection is not
-      yet migrated to new react schema. Once the properties for collection
-      is removed, remove this model */
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'did',
-        defaults: {
-          name: undefined,
-          owner: undefined,
-          comment: undefined,
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-            this.set({'datowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        schema: [
-          {
-            id: 'name', label: gettext('Database'), cell: 'string',
-            editable: false, type: 'text',
-          },{
-            id: 'did', label: gettext('OID'), cell: 'string', mode: ['properties'],
-            editable: false, type: 'text',
-          },{
-            id: 'datowner', label: gettext('Owner'),
-            editable: false, type: 'text', node: 'role',
-            control: Backform.NodeListByNameControl, select2: { allowClear: false },
-          },{
-            id: 'comments', label: gettext('Comment'),
-            editable: false, type: 'multiline',
-          },
-        ],
-      }),
     });
 
     pgBrowser.SecurityGroupSchema = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
index 0715ea1b7..5b02716d3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
@@ -95,20 +95,20 @@ export default class DatabaseSchema extends BaseUISchema {
     return [
       {
         id: 'name', label: gettext('Database'), cell: 'text',
-        editable: false, type: 'text', noEmpty: true,
+        editable: false, type: 'text', noEmpty: true, isCollectionProperty: true,
       },{
         id: 'did', label: gettext('OID'), cell: 'text', mode: ['properties'],
         editable: false, type: 'text',
       },{
         id: 'datowner', label: gettext('Owner'),
         editable: false, type: 'select', options: this.fieldOptions.role,
-        controlProps: { allowClear: false },
+        controlProps: { allowClear: false }, isCollectionProperty: true,
       },{
         id: 'is_sys_obj', label: gettext('System database?'),
         cell: 'switch', type: 'switch', mode: ['properties'],
       },{
         id: 'comments', label: gettext('Comment'),
-        editable: false, type: 'multiline',
+        editable: false, type: 'multiline', isCollectionProperty: true,
       },{
         id: 'encoding', label: gettext('Encoding'),
         editable: false, type: 'select', group: gettext('Definition'),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
index 1a145b4d6..f5f596188 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
@@ -14,8 +14,8 @@ import Notify from '../../../../../../../static/js/helpers/Notifier';
 
 define('pgadmin.node.subscription', [
   'sources/gettext', 'sources/url_for', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, pgAdmin, pgBrowser, Backform) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
+], function(gettext, url_for, $, pgAdmin, pgBrowser) {
 
   // Extend the browser's collection class for subscriptions collection
   if (!pgBrowser.Nodes['coll-subscription']) {
@@ -24,7 +24,7 @@ define('pgadmin.node.subscription', [
         node: 'subscription',
         label: gettext('Subscriptions'),
         type: 'coll-subscription',
-        columns: ['name', 'subowner', 'pub', 'enabled'],
+        columns: ['name', 'subowner', 'proppub', 'enabled'],
         hasStatistics: true,
       });
   }
@@ -74,101 +74,6 @@ define('pgadmin.node.subscription', [
           enable: 'canCreate',
         }]);
       },
-      // Define the model for subscription node
-      model: pgBrowser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          name: undefined,
-          subowner: undefined,
-          pubtable: undefined,
-          connect_timeout: 10,
-          pub:[],
-          enabled:true,
-          create_slot: true,
-          copy_data:true,
-          connect:true,
-          copy_data_after_refresh:false,
-          sync:'off',
-          refresh_pub: false,
-          password: '',
-          sslmode: 'prefer',
-          sslcompression: false,
-          sslcert: '',
-          sslkey: '',
-          sslrootcert: '',
-          sslcrl: '',
-          host: '',
-          hostaddr: '',
-          port: 5432,
-          db: 'postgres',
-        },
-
-        // Default values!
-        initialize: function(attrs, args) {
-          var isNew = (_.size(attrs) === 0);
-          if (isNew) {
-            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
-
-            this.set({'subowner': userInfo.name}, {silent: true});
-          }
-          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
-        },
-
-        // Define the schema for the subscription node
-        schema: [{
-          id: 'name', label: gettext('Name'), type: 'text',
-          mode: ['properties', 'create', 'edit'],
-          visible: function() {
-            if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
-              && !_.isUndefined(this.node_info.server.version) &&
-                this.node_info.server.version >= 100000) {
-              return true;
-            }
-            return false;
-          },
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          type: 'text',
-        },
-        {
-          id: 'subowner', label: gettext('Owner'), type: 'text',
-          control: Backform.NodeListByNameControl, node: 'role',
-          mode: ['edit', 'properties', 'create'], select2: { allowClear: false},
-          disabled: function(m){
-            if(m.isNew())
-              return true;
-            return false;
-          },
-        },
-        {
-          id: 'enabled', label: gettext('Enabled?'),
-          type: 'switch', mode: ['properties'],
-          group: gettext('With'),
-          readonly: 'isConnect', deps :['connect'],
-          helpMessage: gettext('Specifies whether the subscription should be actively replicating, or whether it should be just setup but not started yet.'),
-        },
-        {
-          id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
-          mode: ['properties'],
-        },
-        ],
-        sessChanged: function() {
-          if (!this.isNew() && _.isUndefined(this.attributes['refresh_pub']))
-            return false;
-          return pgBrowser.DataModel.prototype.sessChanged.apply(this);
-        },
-        canCreate: function(itemData, item) {
-          var treeData = pgBrowser.tree.getTreeNodeHierarchy(item),
-            server = treeData['server'];
-
-          // If server is less than 10 then do not allow 'create' menu
-          if (server && server.version < 100000)
-            return false;
-
-          // by default we want to allow create menu
-          return true;
-        },
-      }),
       getSchema: function(treeNodeInfo, itemNodeData){
         return new SubscriptionSchema(
           {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
index bb6b418c6..771e3c03b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.ui.js
@@ -176,7 +176,7 @@ export default class SubscriptionSchema extends BaseUISchema{
       mode: ['properties', 'edit', 'create'],
     },
     {
-      id: 'pub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
+      id: 'proppub', label: gettext('Publication'), type: 'text', group: gettext('Connection'),
       mode: ['properties'],
     },
     {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
index f7a6baf3b..a416821da 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
@@ -1,6 +1,7 @@
 SELECT  sub.oid as oid,
         subname as name,
         subpublications as pub,
+        subpublications as proppub,
         sub.subsynccommit as sync,
         pga.rolname as subowner,
         subslotname as slot_name,
diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
index 1147e352c..0b037813c 100644
--- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
+++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
@@ -582,152 +582,6 @@ define('pgadmin.node.role', [
           },
         );
       },
-      model: pgAdmin.Browser.Node.Model.extend({
-        idAttribute: 'oid',
-        defaults: {
-          oid: null,
-          rolname: undefined,
-          rolcanlogin: false,
-          rolconnlimit: -1,
-          rolsuper: false,
-          rolcreaterole: false,
-          rolcreatedb: false,
-          rolinherit: true,
-          rolcatupdate: false,
-          rolreplication: false,
-          rolvaliduntil: null,
-        },
-        schema: [{
-          id: 'rolname', label: gettext('Name'), type: 'text',
-          readonly: 'readonly',
-        },{
-          id: 'oid', label: gettext('OID'), cell: 'string', mode: ['properties'],
-          editable: false, type: 'text', visible: true,
-        },{
-          id: 'rolvaliduntil', readonly: 'readonly', type: 'text',
-          group: gettext('Definition'), label: gettext('Account expires'),
-          mode: ['properties', 'edit', 'create'], control: 'datetimepicker',
-          deps: ['rolcanlogin'],
-          placeholder: gettext('No Expiry'),
-          helpMessage: gettext('Please note that if you leave this field blank, then password will never expire.'),
-          setMinDate: false,
-        },{
-          id: 'rolconnlimit',  type: 'int', group: gettext('Definition'),
-          label: gettext('Connection limit'), cell: 'integer', min : -1,
-          mode: ['properties', 'edit', 'create'], readonly: 'readonly',
-        },{
-          id: 'rolcanlogin', label: gettext('Can login?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          group: gettext('Privileges'),
-          readonly: 'readonly',
-        },{
-          id: 'rolsuper', label: gettext('Superuser?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          group: gettext('Privileges'),
-          control: Backform.SwitchControl.extend({
-            onChange: function() {
-              Backform.SwitchControl.prototype.onChange.apply(this, arguments);
-
-              this.model.set('rolcatupdate', this.model.get('rolsuper'));
-              this.model.set('rolcreaterole', this.model.get('rolsuper'));
-              this.model.set('rolcreatedb', this.model.get('rolsuper'));
-            },
-          }),
-          readonly: 'readonly',
-        },{
-          id: 'rolcreaterole', label: gettext('Create roles?'),
-          group: gettext('Privileges'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'is_sys_obj', label: gettext('System role?'),
-          cell:'boolean', type: 'switch', mode: ['properties'],
-        },{
-          id: 'description', label: gettext('Comments'), type: 'multiline',
-          group: null, mode: ['properties', 'edit', 'create'],
-          readonly: 'readonly',
-        },{
-          id: 'rolcreatedb', label: gettext('Create databases?'),
-          group: gettext('Privileges'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'rolcatupdate', label: gettext('Update catalog?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          max_version: 90400,
-          group: gettext('Privileges'), readonly: function(m) {
-            return m.get('read_only');
-          },
-          disabled: function(m) {
-            return !m.get('rolsuper');
-          },
-        },{
-          id: 'rolinherit', group: gettext('Privileges'),
-          label: gettext('Inherit rights from the parent roles?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          readonly: 'readonly',
-        },{
-          id: 'rolreplication', group: gettext('Privileges'),
-          label: gettext('Can initiate streaming replication and backups?'),
-          type: 'switch',
-          controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12',
-          controlsClassName: 'pgadmin-controls pg-el-sm-8 pg-el-12',
-          min_version: 90100,
-          readonly: 'readonly',
-        }],
-        readonly: function(m) {
-          if (!m.has('read_only')) {
-            var user = this.node_info.server.user;
-
-            m.set('read_only', !(user.is_superuser || user.can_create_role));
-          }
-
-          return m.get('read_only');
-        },
-        validate: function()
-        {
-          var err = {},
-            errmsg,
-            seclabels = this.get('seclabels');
-
-          if (_.isUndefined(this.get('rolname')) || String(this.get('rolname')).replace(/^\s+|\s+$/g, '') == '') {
-            err['name'] = gettext('Name cannot be empty.');
-            errmsg = err['name'];
-          }
-
-          if (seclabels) {
-            var secLabelsErr;
-            for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
-              secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
-              if (secLabelsErr) {
-                err['seclabels'] = secLabelsErr;
-                errmsg = errmsg || secLabelsErr;
-              }
-            }
-          }
-
-          this.errorModel.clear().set(err);
-
-          if (_.size(err)) {
-            this.trigger('on-status', {msg: errmsg});
-            return errmsg;
-          }
-
-          return null;
-        },
-      }),
     });
   }
 
diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js
index 9f944ff19..240665432 100644
--- a/web/pgadmin/browser/static/js/collection.js
+++ b/web/pgadmin/browser/static/js/collection.js
@@ -7,8 +7,9 @@
 //
 //////////////////////////////////////////////////////////////
 
-import {removeNodeView} from './node_view';
-import Notify from '../../../static/js/helpers/Notifier';
+// import {removeNodeView} from './node_view';
+// import Notify from '../../../static/js/helpers/Notifier';
+import {getPanelView} from './panel_view';
 
 define([
   'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin',
@@ -91,399 +92,14 @@ define([
       canDropCascade: true,
       selectParentNodeOnDelete: false,
       showProperties: function(item, data, panel) {
-        var that = this,
-          j = panel.$container.find('.obj_properties').first(),
-          view = j.data('obj-view'),
-          content = $('<div></div>')
-            .addClass('pg-prop-content col-12 has-pg-prop-btn-group'),
-          node = pgBrowser.Nodes[that.node],
-          $msgContainer = '',
-          // This will be the URL, used for object manipulation.
-          urlBase = this.generate_url(item, 'properties', data),
-          info = pgBrowser.tree.getTreeNodeHierarchy(item),
-          gridSchema = Backform.generateGridColumnsFromModel(
-            info, node.model, 'properties', that.columns
-          ),
-          createButtons = function(buttonsList, location, extraClasses) {
-            // Arguments must be non-zero length array of type
-            // object, which contains following attributes:
-            // label, type, extraClasses, register
-            if (buttonsList && _.isArray(buttonsList) && buttonsList.length > 0) {
-              // All buttons will be created within a single
-              // div area.
-              var btnGroup =
-                $('<div class="pg-prop-btn-group"></div>'),
-                // Template used for creating a button
-                tmpl = _.template([
-                  '<button tabindex="0" type="<%= type %>" ',
-                  'class="btn <%=extraClasses.join(\' \')%>"',
-                  '<% if (disabled) { %> disabled="disabled"<% } %> title="<%-tooltip%>">',
-                  '<span class="<%= icon %>" role="img"></span><% if (label != "") { %>&nbsp;<%-label%><% } %><span class="sr-only"><%-tooltip%></span></button>',
-                ].join(' '));
-              if (location == 'header') {
-                btnGroup.appendTo(that.header);
-              } else {
-                btnGroup.appendTo(that.footer);
-              }
-              if (extraClasses) {
-                btnGroup.addClass(extraClasses);
-              }
-              _.each(buttonsList, function(btn) {
-                // Create the actual button, and append to
-                // the group div
 
-                // icon may not present for this button
-                if (!btn.icon) {
-                  btn.icon = '';
-                }
-                var b = $(tmpl(btn));
-                btnGroup.append(b);
-                // Register is a callback to set callback
-                // for certain operation for this button.
-                btn.register(b);
-              });
-              return btnGroup;
-            }
-            return null;
-          }.bind(panel);
-
-        that.collection = new (node.Collection.extend({
-          url: urlBase,
-          model: node.model,
-        }))();
-        // Add the new column for the multi-select menus
-        if((_.isFunction(that.canDrop) ?
-          that.canDrop.apply(that, [data, item]) : that.canDrop) ||
-              (_.isFunction(that.canDropCascade) ?
-                that.canDropCascade.apply(that, [data, item]) : that.canDropCascade)) {
-          gridSchema.columns.unshift({
-            name: 'oid',
-            cell: Backgrid.Extension.SelectRowCell.extend({
-              initialize: function (options) {
-                this.column = options.column;
-                if (!(this.column instanceof Backgrid.Column)) {
-                  this.column = new Backgrid.Column(this.column);
-                }
-
-                var column = this.column, model = this.model, $el = this.$el;
-                this.listenTo(column, 'change:renderable', function (col, renderable) {
-                  $el.toggleClass('renderable', renderable);
-                });
-
-                if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass('renderable width_percent_3');
-
-                this.listenTo(model, 'backgrid:select', this.toggleCheckbox);
-              },
-              toggleCheckbox: function(model, selected) {
-                if (this.checkbox().prop('disabled') === false) {
-                  this.checkbox().prop('checked', selected).change();
-                }
-              },
-              render: function() {
-                let model = this.model.toJSON();
-                // canDrop can be set to false for individual row from the server side to disable the checkbox
-                let disabled = ('canDrop' in model && model.canDrop === false);
-                let id = `row-${_.uniqueId(model.oid || model.name)}`;
-
-                this.$el.empty().append(`
-                  <div class="custom-control custom-checkbox custom-checkbox-no-label">
-                    <input tabindex="-1" type="checkbox" class="custom-control-input" id="${id}" ${disabled?'disabled':''}/>
-                    <label class="custom-control-label" for="${id}">
-                      <span class="sr-only">` + gettext('Select') + `<span>
-                    </label>
-                  </div>
-                `);
-                this.delegateEvents();
-                return this;
-              },
-            }),
-            headerCell: Backgrid.Extension.SelectAllHeaderCell,
-          });
-        }
-        /* Columns should be always non-editable  */
-        gridSchema.columns.forEach((col)=>{
-          col.disabled = true;
-        });
-
-        // Get the list of selected models, before initializing the grid
-        // again.
-        var selectedModels = [];
-        if(!_.isUndefined(that.grid) && 'collection' in that.grid){
-          selectedModels = that.grid.getSelectedModels();
-        }
-
-        // Initialize a new Grid instance
-        that.grid = new Backgrid.Grid({
-          emptyText: gettext('No data found'),
-          columns: gridSchema.columns,
-          collection: that.collection,
-          className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
-        });
-
-        var gridView = {
-          'remove': function() {
-            if (this.grid) {
-              if (this.grid.collection) {
-                this.grid.collection.reset([], {silent: true});
-                delete (this.grid.collection);
-              }
-              delete (this.grid);
-              this.grid = null;
-            }
-          },
-          grid: that.grid,
-        };
-
-        if (view) {
-          // Cache the current IDs for next time
-          $(panel).data('node-prop', urlBase);
-
-          // Reset the data object
-          j.data('obj-view', null);
-        }
-
-        /* Remove any dom rendered by getNodeView */
-        removeNodeView(j[0]);
-        // Make sure the HTML element is empty.
-        j.empty();
-        j.data('obj-view', gridView);
-
-        $msgContainer = '<div role="status" class="pg-panel-message pg-panel-properties-message">' +
-         gettext('Retrieving data from the server...') + '</div>';
-
-        $msgContainer = $($msgContainer).appendTo(j);
-
-        that.header = $('<div></div>').addClass(
-          'pg-prop-header'
+        let container =  panel.$container[0];
+        getPanelView(
+          pgBrowser.tree,
+          container,
+          pgBrowser,
+          panel._type
         );
-
-        // Render the buttons
-        var buttons = [];
-
-        buttons.push({
-          label: '',
-          type: 'delete',
-          tooltip: gettext('Delete/Drop'),
-          extraClasses: ['btn-primary-icon m-1', 'delete_multiple'],
-          icon: 'fa fa-trash-alt',
-          disabled:  (_.isFunction(that.canDrop)) ? !(that.canDrop.apply(self, [data, item])) : (!that.canDrop),
-          register: function(btn) {
-            btn.on('click',() => {
-              onDrop('drop');
-            });
-          },
-        });
-
-        buttons.push({
-          label: '',
-          type: 'delete',
-          tooltip: gettext('Drop Cascade'),
-          extraClasses: ['btn-primary-icon m-1', 'delete_multiple_cascade'],
-          icon: 'pg-font-icon icon-drop_cascade',
-          disabled: (_.isFunction(that.canDropCascade)) ? !(that.canDropCascade.apply(self, [data, item])) : (!that.canDropCascade),
-          register: function(btn) {
-            btn.on('click',() => {
-              onDrop('dropCascade');
-            });
-          },
-        });
-
-        createButtons(buttons, 'header', 'pg-prop-btn-group-above');
-
-        // Render subNode grid
-        content.append('<div class="pg-prop-coll-container"></div>');
-        content.find('.pg-prop-coll-container').append(that.grid.render().$el);
-
-        var timer;
-        var getAjaxHook = function() {
-          $.ajax({
-            url: urlBase,
-            type: 'GET',
-            beforeSend: function(xhr) {
-              xhr.setRequestHeader(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
-              // Generate a timer for the request
-              timer = setTimeout(function() {
-                // notify user if request is taking longer than 1 second
-
-                if (!$msgContainer.text()== 'Failed to retrieve data from the server.')
-                  $msgContainer.text(gettext('Retrieving data from the server...'));
-                $msgContainer.removeClass('d-none');
-                if (self.grid) {
-                  self.grid.remove();
-                }
-              }, 1000);
-            },
-          }).done(function(res) {
-            clearTimeout(timer);
-
-            if (_.isUndefined(that.grid) || _.isNull(that.grid)) return;
-
-            that.data = res;
-
-            if (that.data.length > 0) {
-
-              if (!$msgContainer.hasClass('d-none')) {
-                $msgContainer.addClass('d-none');
-              }
-              that.header.appendTo(j);
-              j.append(content);
-
-              // Listen scroll event to load more rows
-              $('.pg-prop-content').on('scroll', that.__loadMoreRows.bind(that));
-
-              that.collection.reset(that.data.splice(0, 50));
-
-              // Listen to select all checkbox event
-              that.collection.on('backgrid:select-all', that.__loadAllRows.bind(that));
-
-              // Trigger the backgrid:select event for already selected items
-              // as we have created a new grid instance.
-              if(selectedModels.length > 0) {
-                that.collection.each(function (model) {
-                  for(let model_val of selectedModels){
-                    if (model_val.id == model.id){
-                      model.trigger('backgrid:select', model, true);
-                    }
-                  }
-                });
-              }
-            } else {
-            // Do not listen the scroll event
-              $('.pg-prop-content').off('scroll', that.__loadMoreRows);
-
-              $msgContainer.text(gettext('No properties are available for the selected object.'));
-
-            }
-            selectedModels = [];
-          }).fail(function(xhr, error) {
-            pgBrowser.Events.trigger(
-              'pgadmin:node:retrieval:error', 'properties', xhr, error.message, item, that
-            );
-            if (!Alertify.pgHandleItemError(xhr, error.message, {
-              item: item,
-              info: info,
-            })) {
-              Notify.pgNotifier(
-                error, xhr, gettext('Error retrieving properties - %s', error.message || that.label),
-                function(msg) {
-                  if(msg === 'CRYPTKEY_SET') {
-                    getAjaxHook();
-                  } else {
-                    console.warn(arguments);
-                  }
-                }
-              );
-            }
-            // show failed message.
-            $msgContainer.text(gettext('Failed to retrieve data from the server.'));
-          });
-        };
-        getAjaxHook();
-
-        var onDrop = function(type, confirm=true) {
-          let sel_row_models = this.grid.getSelectedModels(),
-            sel_rows = [],
-            sel_item = pgBrowser.tree.selected(),
-            d = sel_item ? pgBrowser.tree.itemData(sel_item) : null,
-            sel_node = d && pgBrowser.Nodes[d._type],
-            url = undefined,
-            msg = undefined,
-            title = undefined;
-
-          if (sel_node && sel_node.type && sel_node.type == 'coll-constraints') {
-            // In order to identify the constraint type, the type should be passed to the server
-            sel_rows = sel_row_models.map(row => ({id: row.get('oid'), _type: row.get('_type')}));
-          }
-          else {
-            sel_rows = sel_row_models.map(row => row.id);
-          }
-
-          if (sel_rows.length === 0) {
-            Notify.alert(gettext('Drop Multiple'),
-              gettext('Please select at least one object to delete.')
-            );
-            return;
-          }
-
-          if (!sel_node)
-            return;
-
-          if (type === 'dropCascade') {
-            url = sel_node.generate_url(sel_item, 'delete');
-            msg = gettext('Are you sure you want to drop all the selected objects and all the objects that depend on them?');
-            title = gettext('DROP CASCADE multiple objects?');
-          } else {
-            url = sel_node.generate_url(sel_item, 'drop');
-            msg = gettext('Are you sure you want to drop all the selected objects?');
-            title = gettext('DROP multiple objects?');
-          }
-
-          let dropAjaxHook = function() {
-            $.ajax({
-              url: url,
-              type: 'DELETE',
-              data: JSON.stringify({'ids': sel_rows}),
-              contentType: 'application/json; charset=utf-8',
-            }).done(function(res) {
-              if (res.success == 0) {
-                pgBrowser.report_error(res.errormsg, res.info);
-              } else {
-                $(pgBrowser.panels['properties'].panel).removeData('node-prop');
-                pgBrowser.Events.trigger(
-                  'pgadmin:browser:tree:refresh', sel_item || pgBrowser.tree.selected(), {
-                    success: function() {
-                      setTimeout(function() {
-                        pgBrowser.tree.select(sel_item);
-                        sel_node.callbacks.selected.apply(sel_node, [sel_item]);
-                      }, 100);
-                    },
-                  });
-              }
-              return true;
-            }).fail(function(xhr, error) {
-              Notify.pgNotifier(
-                error, xhr,
-                gettext('Error dropping %s', d._label.toLowerCase()),
-                function(alertMsg) {
-                  if (alertMsg == 'CRYPTKEY_SET') {
-                    onDrop(type, false);
-                  } else {
-                    $(pgBrowser.panels['properties'].panel).removeData('node-prop');
-                    pgBrowser.Events.trigger(
-                      'pgadmin:browser:tree:refresh', sel_item || pgBrowser.tree.selected(), {
-                        success: function() {
-                          sel_node.callbacks.selected.apply(sel_node, [sel_item]);
-                        },
-                      }
-                    );
-                  }
-                }
-              );
-            });
-          };
-
-          if(confirm) {
-            Notify.confirm(title, msg, dropAjaxHook, null);
-          } else {
-            dropAjaxHook();
-          }
-        }.bind(that);
-      },
-      __loadMoreRows: function(e) {
-        let elem = e.currentTarget;
-        if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
-          if (this.data.length > 0) {
-            this.collection.add(this.data.splice(0, 50));
-          }
-        }
-      },
-      __loadAllRows: function(tmp, checked) {
-        if (this.data.length > 0) {
-          this.collection.add(this.data);
-          this.collection.each(function (model) {
-            model.trigger('backgrid:select', model, checked);
-          });
-        }
       },
       generate_url: function(item, type) {
         /*
diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index 9e6d3d543..21ae4c06d 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -1082,8 +1082,6 @@ define('pgadmin.browser.node', [
             b.panels['properties'] &&
             b.panels['properties'].panel &&
             b.panels['properties'].panel.isVisible()) {
-            // Show object properties (only when the 'properties' tab
-            // is active).
             this.showProperties(item, d, b.panels['properties'].panel);
           }
         }
@@ -1259,20 +1257,20 @@ define('pgadmin.browser.node', [
             d = i && tree.itemData(i),
             treeHierarchy = tree.getTreeNodeHierarchy(i);
 
-          if (_.isEqual($(this).data('node-prop'), treeHierarchy)) {
-            return;
-          }
-
           // Cache the current IDs for next time
           $(this).data('node-prop', treeHierarchy);
 
           /* Remove any dom rendered by getNodeView */
-          removeNodeView(j[0]);
-          /* getSchema is a schema for React. Get the react node view */
+          removeNodeView(pgBrowser.panels['properties'].panel.$container[0]);
+
+          var containerProperties =  pgBrowser.panels['properties'].panel.$container;
+          containerProperties.addClass('pg-panel-content pg-no-overflow pg-el-container');
+
+
           if(that.getSchema) {
             let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
             getNodeView(
-              that.type, treeNodeInfo, 'properties', data, 'tab', j[0], this, onEdit
+              that.type, treeNodeInfo, 'properties', data, 'tab', containerProperties[0], this, onEdit
             );
             return;
           }
diff --git a/web/pgadmin/browser/static/js/node_ajax.js b/web/pgadmin/browser/static/js/node_ajax.js
index 14a9afa3c..19ac76562 100644
--- a/web/pgadmin/browser/static/js/node_ajax.js
+++ b/web/pgadmin/browser/static/js/node_ajax.js
@@ -25,8 +25,9 @@ export function generateCollectionURL(item, type) {
   };
   var treeInfo = pgAdmin.Browser.tree.getTreeNodeHierarchy(item);
   var actionType = type in opURL ? opURL[type] : type;
+  var nodeType = type === 'properties' ? nodeObj.type : nodeObj.node;
   return generate_url(
-    pgAdmin.Browser.URL, treeInfo, actionType, nodeObj.node,
+    pgAdmin.Browser.URL, treeInfo, actionType, nodeType,
     collectionPickFunction
   );
 }
diff --git a/web/pgadmin/browser/static/js/node_view.jsx b/web/pgadmin/browser/static/js/node_view.jsx
index b9ec79e90..453f20c95 100644
--- a/web/pgadmin/browser/static/js/node_view.jsx
+++ b/web/pgadmin/browser/static/js/node_view.jsx
@@ -16,7 +16,6 @@ import {getHelpUrl, getEPASHelpUrl} from 'pgadmin.help';
 import SchemaView from 'sources/SchemaView';
 import { generateNodeUrl } from './node_ajax';
 import Notify from '../../../static/js/helpers/Notifier';
-
 import gettext from 'sources/gettext';
 import 'wcdocker';
 
diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js
index fbbc56bd5..c0bd9178f 100644
--- a/web/pgadmin/browser/static/js/panel.js
+++ b/web/pgadmin/browser/static/js/panel.js
@@ -122,14 +122,32 @@ define(
                 that.resizedContainer.apply(myPanel);
               }
 
-              // Bind events only if they are configurable
-              if (that.canHide) {
-                _.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
-                  function(ev) {
-                    myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
-                  });
+
+
+              if (myPanel._type == 'dashboard') {
+                getPanelView(
+                  pgBrowser.tree,
+                  $container[0],
+                  pgBrowser,
+                  myPanel._type
+                );
               }
 
+              // Rerender the dashboard panel when preference value 'show graph' gets changed.
+              pgBrowser.onPreferencesChange('dashboards', function() {
+                getPanelView(
+                  pgBrowser.tree,
+                  $container[0],
+                  pgBrowser,
+                  myPanel._type
+                );
+              });
+
+              _.each([wcDocker.EVENT.CLOSED, wcDocker.EVENT.VISIBILITY_CHANGED],
+                function(ev) {
+                  myPanel.on(ev, that.handleVisibility.bind(myPanel, ev));
+                });
+
               pgBrowser.Events.on('pgadmin-browser:tree:selected', () => {
 
                 if(myPanel.isVisible()) {
@@ -141,6 +159,18 @@ define(
                   );
                 }
               });
+
+              pgBrowser.Events.on('pgadmin-browser:tree:refreshing', () => {
+
+                if(myPanel.isVisible()) {
+                  getPanelView(
+                    pgBrowser.tree,
+                    $container[0],
+                    pgBrowser,
+                    myPanel._type
+                  );
+                }
+              });
             },
           });
         }
@@ -205,11 +235,6 @@ define(
         }
       },
       handleVisibility: function(eventName) {
-        // Supported modules
-        let type_module = {
-          dashboard: pgAdmin.Dashboard,
-        };
-        let module = type_module[this._type];
         if (_.isNull(pgBrowser.tree)) return;
 
         let selectedPanel = pgBrowser.docker.findPanels(this._type)[0];
@@ -219,18 +244,6 @@ define(
           .scene()
           .find('.pg-panel-content');
 
-        if (this._type === 'dashboard') {
-          if (eventName == 'panelClosed') {
-            module.toggleVisibility.call(module, false, true);
-          } else if (eventName == 'panelVisibilityChanged') {
-            module.toggleVisibility.call(
-              module,
-              pgBrowser.docker.findPanels(this._type)[0].isVisible(),
-              false
-            );
-          }
-        }
-
         if (isPanelVisible) {
           if (eventName == 'panelClosed') {
             removePanelView($container[0]);
diff --git a/web/pgadmin/browser/static/js/panel_view.jsx b/web/pgadmin/browser/static/js/panel_view.jsx
index cf0a5a07e..39122755d 100644
--- a/web/pgadmin/browser/static/js/panel_view.jsx
+++ b/web/pgadmin/browser/static/js/panel_view.jsx
@@ -13,6 +13,11 @@ import Theme from 'sources/Theme';
 import Dependencies from '../../../misc/dependencies/static/js/Dependencies';
 import Dependents from '../../../misc/dependents/static/js/Dependents';
 import Statistics from '../../../misc/statistics/static/js/Statistics';
+import SQL from '../../../misc/sql/static/js/SQL';
+import Dashboard from '../../../dashboard/static/js/Dashboard';
+import _ from 'lodash';
+import { CollectionNodeView } from '../../../misc/properties/CollectionNodeProperties';
+
 
 /* The entry point for rendering React based view in properties, called in node.js */
 export function getPanelView(
@@ -21,10 +26,33 @@ export function getPanelView(
   pgBrowser,
   panelType
 ) {
-  let item = tree.selected(),
-    nodeData = item && tree.itemData(item),
-    node = item && nodeData && pgBrowser.Nodes[nodeData._type],
+  let item = !_.isNull(tree)? tree.selected(): null,
+
+    nodeData, node, treeNodeInfo, preferences;
+  if (item){
+    nodeData = tree.itemData(item);
+    node = nodeData && pgBrowser.Nodes[nodeData._type];
     treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
+    preferences = pgBrowser.get_preferences_for_module('dashboards');
+  }
+  if (panelType == 'dashboard') {
+    ReactDOM.render(
+      <Theme>
+        <Dashboard
+          treeNodeInfo={treeNodeInfo}
+          pgBrowser={pgBrowser}
+          nodeData={nodeData}
+          node={node}
+          item={item}
+          preferences={preferences}
+          did={((!_.isUndefined(treeNodeInfo)) && (!_.isUndefined(treeNodeInfo['database']))) ? treeNodeInfo['database']._id: 0}
+          sid={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo['server']._id : ''}
+          serverConnected={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo.server.connected: false}
+        />
+      </Theme>,
+      container
+    );
+  }
 
 
   if (panelType == 'statistics') {
@@ -41,6 +69,20 @@ export function getPanelView(
       container
     );
   }
+  if (panelType == 'properties') {
+    ReactDOM.render(
+      <Theme>
+        <CollectionNodeView
+          treeNodeInfo={treeNodeInfo}
+          item={item}
+          itemNodeData={nodeData}
+          node={node}
+          pgBrowser={pgBrowser}
+        />
+      </Theme>,
+      container
+    );
+  }
   if (panelType == 'dependencies') {
     ReactDOM.render(
       <Theme>
@@ -69,6 +111,20 @@ export function getPanelView(
       container
     );
   }
+  if (panelType == 'sql') {
+    ReactDOM.render(
+      <Theme>
+        <SQL
+          treeNodeInfo={treeNodeInfo}
+          pgBrowser={pgBrowser}
+          nodeData={nodeData}
+          node={node}
+          item={item}
+        />
+      </Theme>,
+      container
+    );
+  }
 }
 
 /* When switching from normal node to collection node, clean up the React mounted DOM */
diff --git a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
new file mode 100644
index 000000000..69080e47d
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
@@ -0,0 +1,67 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import BaseUISchema from 'sources/SchemaView/base_schema.ui';
+
+export default class ActiveQuery extends BaseUISchema {
+  constructor(initValues) {
+    super({
+      ...initValues,
+    });
+
+  }
+  
+  get baseFields() {
+    return [
+
+      {
+        id: 'backend_type',
+        label: gettext('Backend type'),
+        type: 'text',
+        editable: true,
+        noEmpty: true,
+        readonly: true,
+        mode: ['properties'],
+        group: gettext('Details'),
+        disabled: true
+      },
+      {
+        id: 'query_start',
+        label: gettext('Query started at'),
+        type: 'text',
+        editable: false,
+        readonly: true,
+        group: gettext('Details'),
+        disabled: true
+
+      },
+      {
+        id: 'state_change',
+        label: gettext('Last state changed at'),
+        type: 'text',
+        editable: false,
+        readonly: true,
+        group: gettext('Details'),
+        disabled: true
+      },
+      {
+        id: 'query',
+        label: gettext('SQL'),
+        cell: 'string',
+        editable: false,
+        readonly: true,
+        type: 'sql',
+        group: gettext('Details'),
+      },
+    ];
+
+  }
+
+}
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
new file mode 100644
index 000000000..9c008b3cb
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -0,0 +1,907 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+// eslint-disable-next-line react/display-name
+import React, { useEffect, useState } from 'react';
+import gettext from 'sources/gettext';
+import PropTypes from 'prop-types';
+import getApiInstance from 'sources/api_instance';
+import PgTable from 'sources/components/PgTable';
+import { makeStyles } from '@material-ui/core/styles';
+import url_for from 'sources/url_for';
+import Graphs from './Graphs';
+import Notify from '../../../static/js/helpers/Notifier';
+import { Box, Tab, Tabs } from '@material-ui/core';
+import { PgIconButton } from '../../../static/js/components/Buttons';
+import CancelIcon from '@mui/icons-material/Cancel';
+import SquareIcon from '@mui/icons-material/Square';
+import ArrowRightOutlinedIcon from '@mui/icons-material/ArrowRightOutlined';
+import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';
+import WelcomeDashboard from './WelcomeDashboard';
+import ActiveQuery from './ActiveQuery.ui';
+import _ from 'lodash';
+
+function parseData(data) {
+  var res = [];
+
+  data.forEach((row) => {
+    res.push({ ...row, icon: '' });
+  });
+  return res;
+}
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    height: '100%',
+    background: theme.palette.grey[400],
+    overflow: 'auto',
+    padding: '8px',
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+  },
+  fixedSizeList: {
+    overflowX: 'hidden !important',
+    overflow: 'overlay !important',
+    height: 'auto !important',
+  },
+  dashboardPanel: {
+    height: '100%',
+    background: theme.palette.grey[400],
+  },
+  cardHeader: {
+    padding: '0.25rem 0.5rem',
+    fontWeight: 'bold',
+    backgroundColor: theme.otherVars.tableBg,
+    borderBottom: '1px solid',
+    borderBottomColor: theme.otherVars.borderColor,
+  },
+  searchPadding: {
+    display: 'flex',
+    flex: 2.5,
+  },
+  component: {
+    padding: '8px',
+  },
+  searchInput: {
+    flex: 1,
+  },
+  panelIcon: {
+    width: '80%',
+    margin: '0 auto',
+    marginTop: '25px !important',
+    position: 'relative',
+    textAlign: 'center',
+  },
+  panelMessage: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+  },
+  panelContent: {
+    ...theme.mixins.panelBorder,
+    flexDirection: 'column',
+    overflow: 'hidden !important',
+    flexGrow: 1
+  },
+  terminateButton: {
+    color: theme.palette.error.main
+  },
+  buttonClick: {
+    backgroundColor: theme.palette.grey[400]
+  }
+}));
+
+/* eslint-disable react/display-name */
+export default function Dashboard({
+  nodeData,
+  node,
+  item,
+  pgBrowser,
+  preferences,
+  sid,
+  did,
+  treeNodeInfo,
+  ...props
+}) {
+  const classes = useStyles();
+  let tab = ['Sessions', 'Locks', 'Prepared Transactions'];
+  const [dashData, setdashData] = useState([]);
+  const [msg, setMsg] = useState('');
+  const[infoMsg, setInfo] = useState('');
+  const [val, setVal] = useState(0);
+  const [schemaDict, setSchemaDict] = React.useState({});
+
+  if (!did) {
+    tab.push('Configuration');
+  }
+  val == 3 && did && setVal(0);
+  const tabChanged = (e, tabVal) => {
+    setVal(tabVal);
+  };
+
+  const serverConfigColumns = [
+    {
+      accessor: 'name',
+      Header: gettext('Name'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 110,
+    },
+    {
+      accessor: 'category',
+      Header: gettext('Category'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'setting',
+      Header: gettext('Setting'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'unit',
+      Header: gettext('Unit'),
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 30,
+    },
+    {
+      accessor: 'short_desc',
+      Header: gettext('Description'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const activityColumns = [
+    {
+      accessor: 'terminate_query',
+      Header: () => null,
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 16,
+      maxWidth: 30,
+      id: 'btn-terminate',
+      // eslint-disable-next-line react/display-name
+      Cell: ({ row }) => {
+        var terminate_session_url =
+          url_for('dashboard.index') + 'terminate_session' + '/' + sid,
+          title = gettext('Terminate Session?'),
+          txtConfirm = gettext(
+            'Are you sure you wish to terminate the session?'
+          ),
+          txtSuccess = gettext('Session terminated successfully.'),
+          txtError = gettext(
+            'An error occurred whilst terminating the active query.'
+          );
+        const action_url = did
+          ? terminate_session_url + '/' + did
+          : terminate_session_url;
+
+        const api = getApiInstance();
+
+        return (
+          <PgIconButton
+            size="xs"
+            noBorder
+            icon={<CancelIcon />}
+            className={classes.terminateButton}
+            onClick={() => {
+              if (
+                !canTakeAction(row, 'terminate')
+              )
+                return;
+              let url = action_url + '/' + row.values.pid;
+              Notify.confirm(
+                title,
+                txtConfirm,
+                function () {
+                  api
+                    .delete(url)
+                    .then(function (res) {
+                      if (res.data == gettext('Success')) {
+                        setInfo(txtSuccess);
+                        Notify.success(txtSuccess);
+                      } else {
+                        setInfo(txtError);
+                        Notify.error(txtError);
+                      }
+                    })
+                    .catch(function (error) {
+                      Notify.alert(
+                        gettext('Failed to retrieve data from the server.'),
+                        gettext(error.message)
+                      );
+                    });
+                },
+                function () {
+                  return true;
+                }
+              );
+            }}
+            color="default"
+            aria-label="Terminate Session?"
+            title={gettext('Terminate Session?')}
+          ></PgIconButton>
+        );
+      },
+    },
+    {
+      accessor: 'cancel_Query',
+      Header: () => null,
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 16,
+      maxWidth: 30,
+      id: 'btn-cancel',
+      Cell: ({ row }) => {
+        var cancel_query_url =
+          url_for('dashboard.index') + 'cancel_query' + '/' + sid,
+          title = gettext('Cancel Active Query?'),
+          txtConfirm = gettext(
+            'Are you sure you wish to cancel the active query?'
+          ),
+          txtSuccess = gettext('Active query cancelled successfully.'),
+          txtError = gettext(
+            'An error occurred whilst cancelling the active query.'
+          );
+
+        const action_url = did ? cancel_query_url + '/' + did : cancel_query_url;
+
+        const api = getApiInstance();
+
+        return (
+          <PgIconButton
+            size="xs"
+            noBorder
+            icon={<SquareIcon fontSize="small" />}
+            onClick={() => {
+              if (!canTakeAction(row, 'cancel'))
+                return;
+              let url = action_url + '/' + row.values.pid;
+              Notify.confirm(
+                title,
+                txtConfirm,
+                function () {
+                  api
+                    .delete(url)
+                    .then(function (res) {
+                      if (res.data == gettext('Success')) {
+                        setInfo(txtSuccess);
+                        Notify.success(txtSuccess);
+                      } else {
+                        setInfo(txtError);
+                        Notify.error(txtError);
+                      }
+                    })
+                    .catch(function (error) {
+                      Notify.alert(
+                        gettext('Failed to retrieve data from the server.'),
+                        gettext(error.message)
+                      );
+                    });
+                },
+                function () {
+                  return true;
+                }
+              );
+            }}
+            color="default"
+            aria-label="Cancel the query"
+            title={gettext('Cancel the active query')}
+          ></PgIconButton>
+        );
+      },
+    },
+    {
+      accessor: 'view_active_query',
+      Header: () => null,
+      sortble: true,
+      resizable: true,
+      disableGlobalFilter: false,
+      minWidth: 16,
+      maxWidth: 30,
+      id: 'btn-edit',
+      Cell: ({ row }) => {
+        let canEditRow = true;
+        return (
+          <PgIconButton
+            className={row.isExpanded ?classes.buttonClick : ''}
+            icon={
+              row.isExpanded ? (
+                <ArrowDropDownOutlinedIcon  />
+              ) : (
+                <ArrowRightOutlinedIcon />
+              )
+            }
+            size="xs"
+            noBorder
+            onClick={(e) => {
+              e.preventDefault();
+              row.toggleRowExpanded(!row.isExpanded);
+              if(!(row.id in schemaDict)){
+                let schema = new ActiveQuery({
+                  query: row.original.query,
+                  backend_type: row.original.backend_type,
+                  state_change: row.original.state_change,
+                  query_start: row.original.query_start,
+                });
+                setSchemaDict(prevState => ({
+                  ...prevState,
+                  [row.id]: schema
+                }));
+              }
+            }}
+            disabled={!canEditRow}
+            aria-label="View the active session details"
+            title={gettext('View the active session details')}
+          />
+        );
+      },
+    },
+    {
+      accessor: 'pid',
+      Header: gettext('PID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'datname',
+      Header: gettext('Database'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 80,
+      isVisible: !did ? true: false
+    },
+    {
+      accessor: 'usename',
+      Header: gettext('User'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 80,
+    },
+    {
+      accessor: 'application_name',
+      Header: gettext('Application'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'client_addr',
+      Header: gettext('Client'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'backend_start',
+      Header: gettext('Backend start'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'xact_start',
+      Header: gettext('Transaction start'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 150,
+    },
+    {
+      accessor: 'state',
+      Header: gettext('State'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+
+    {
+      accessor: 'waiting',
+      Header: gettext('Waiting'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      isVisible: treeNodeInfo?.server?.version < 90600
+    },
+    {
+      accessor: 'wait_event',
+      Header: gettext('Wait event'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'blocking_pids',
+      Header: gettext('Blocking PIDs'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const databaseLocksColumns = [
+    {
+      accessor: 'pid',
+      Header: gettext('PID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'datname',
+      Header: gettext('Database'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 80,
+      isVisible: !did ? true: false
+    },
+    {
+      accessor: 'locktype',
+      Header: gettext('Lock type'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 60,
+    },
+    {
+      accessor: 'relation',
+      Header: gettext('Target relation'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'page',
+      Header: gettext('Page'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'tuple',
+      Header: gettext('Tuple'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'virtualxid',
+      Header: gettext('vXID (target)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 100,
+      maxWidth: 100,
+    },
+    {
+      accessor: 'transactionid',
+      Header: gettext('XID (target)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 100,
+    },
+    {
+      accessor: 'classid',
+      Header: gettext('Class'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 50,
+    },
+    {
+      accessor: 'objid',
+      Header: gettext('Object ID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 100,
+    },
+    {
+      accessor: 'virtualtransaction',
+      Header: gettext('vXID (owner)'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 80,
+    },
+    {
+      accessor: 'mode',
+      Header: gettext('Mode'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      id: 'granted',
+      accessor: 'granted',
+      Header: gettext('Granted?'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 50,
+      maxWidth: 80,
+      Cell: ({ value }) => String(value)
+    },
+  ];
+
+  const databasePreparedColumns = [
+    {
+      accessor: 'git',
+      Header: gettext('Name'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'datname',
+      Header: gettext('Database'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+      minWidth: 26,
+      maxWidth: 80,
+      isVisible: !did ? true: false
+    },
+    {
+      accessor: 'Owner',
+      Header: gettext('Owner'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'transaction',
+      Header: gettext('XID'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      accessor: 'prepared',
+      Header: gettext('Prepared at'),
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ];
+
+  const canTakeAction = (row, cellAction) => {
+    // We will validate if user is allowed to cancel the active query
+    // If there is only one active session means it probably our main
+    // connection session
+    cellAction = cellAction || null;
+    var pg_version = treeNodeInfo.server.version || null,
+      is_cancel_session = cellAction === 'cancel',
+      txtMessage,
+      maintenance_database = treeNodeInfo.server.db,
+      is_super_user,
+      current_user;
+
+    var can_signal_backend =
+      treeNodeInfo.server && treeNodeInfo.server.user
+        ? treeNodeInfo.server.user.can_signal_backend
+        : false;
+
+    if (
+      treeNodeInfo.server &&
+      treeNodeInfo.server.user &&
+      treeNodeInfo.server.user.is_superuser
+    ) {
+      is_super_user = true;
+    } else {
+      is_super_user = false;
+      current_user =
+        treeNodeInfo.server && treeNodeInfo.server.user
+          ? treeNodeInfo.server.user.name
+          : null;
+    }
+
+    // With PG10, We have background process showing on dashboard
+    // We will not allow user to cancel them as they will fail with error
+    // anyway, so better usability we will throw our on notification
+
+    // Background processes do not have database field populated
+    if (pg_version && pg_version >= 100000 && !row.original.datname) {
+      if (is_cancel_session) {
+        txtMessage = gettext('You cannot cancel background worker processes.');
+      } else {
+        txtMessage = gettext(
+          'You cannot terminate background worker processes.'
+        );
+      }
+      Notify.info(txtMessage);
+      return false;
+      // If it is the last active connection on maintenance db then error out
+    } else if (
+      maintenance_database == row.original.datname &&
+      row.original.state == 'active'
+    ) {
+      if (is_cancel_session) {
+        txtMessage = gettext(
+          'You are not allowed to cancel the main active session.'
+        );
+      } else {
+        txtMessage = gettext(
+          'You are not allowed to terminate the main active session.'
+        );
+      }
+      Notify.error(txtMessage);
+      return false;
+    } else if (is_cancel_session && row.original.state == 'idle') {
+      // If this session is already idle then do nothing
+      Notify.info(gettext('The session is already in idle state.'));
+      return false;
+    } else if (can_signal_backend) {
+      // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
+      return true;
+    } else if (is_super_user) {
+      // Super user can do anything
+      return true;
+    } else if (current_user && current_user == treeNodeInfo.server.user) {
+      // Non-super user can cancel only their active queries
+      return true;
+    } else {
+      // Do not allow to cancel someone else session to non-super user
+      if (is_cancel_session) {
+        txtMessage = gettext(
+          'Superuser privileges are required to cancel another users query.'
+        );
+      } else {
+        txtMessage = gettext(
+          'Superuser privileges are required to terminate another users query.'
+        );
+      }
+      Notify.error(txtMessage);
+      return false;
+    }
+  };
+
+  useEffect(() => {
+    let url,
+      message = gettext(
+        'Please connect to the selected server to view the dashboard.'
+      );
+
+    if (sid && props.serverConnected) {
+
+      if (val === 0) {
+        url = url_for('dashboard.activity');
+      } else if (val === 1) {
+        url = url_for('dashboard.locks');
+      } else if (val === 2) {
+        url = url_for('dashboard.prepared');
+      } else {
+        url = url_for('dashboard.config');
+      }
+
+      message = gettext('Loading dashboard...');
+      if (did) url += sid + '/' + did;
+      else url += sid;
+
+      const api = getApiInstance();
+      if (node) {
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            setdashData(parseData(res.data));
+          })
+          .catch((e) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(e.message)
+            );
+            // show failed message.
+            setMsg(gettext('Failed to retrieve data from the server.'));
+          });
+      } else {
+        setMsg(message);
+      }
+    }
+    if (message != '') {
+      setMsg(message);
+    }
+  }, [nodeData, val, did, preferences, infoMsg]);
+
+  return (
+    <>
+      {sid && props.serverConnected ? (
+        <Box className={classes.dashboardPanel}>
+          <Box className={classes.emptyPanel}>
+            {!_.isUndefined(preferences) && preferences.show_graphs && (
+              <Graphs
+                preferences={preferences}
+                sid={sid}
+                did={did}
+                pageVisible={true}
+              ></Graphs>
+            )}
+            <Box className={classes.panelContent}>
+              <Box
+                className={classes.cardHeader}
+                title={gettext('Server activity')}
+              >
+                {gettext('Server activity')}{' '}
+              </Box>
+              <Tabs
+                value={val}
+                onChange={tabChanged}
+                className={classes.searchInput}
+              >
+                {tab.map((tabValue, i) => {
+                  return <Tab key={i} label={tabValue} />;
+                })}
+              </Tabs>
+
+              <PgTable
+                columns={
+                  val === 0
+                    ? activityColumns
+                    : val === 1
+                      ? databaseLocksColumns
+                      : val == 2
+                        ? databasePreparedColumns
+                        : serverConfigColumns
+                }
+                data={dashData}
+                schema={schemaDict}
+                offset={145}
+              ></PgTable>
+            </Box>
+          </Box>
+        </Box>
+      ) : sid && !props.serverConnected ? (
+        <Box className={classes.dashboardPanel}>
+          <div className={classes.emptyPanel}>
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          </div>
+        </Box>
+      ) : (
+        <WelcomeDashboard
+          pgBrowser={pgBrowser}
+          node={node}
+          itemData={nodeData}
+          item={item}
+          sid={sid}
+          did={did}
+        />
+      )}
+    </>
+  );
+}
+
+Dashboard.propTypes = {
+  node: PropTypes.func,
+  itemData: PropTypes.object,
+  nodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  item: PropTypes.object,
+  pgBrowser: PropTypes.object,
+  preferences: PropTypes.object,
+  sid: PropTypes.string,
+  did: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
+  row: PropTypes.object,
+  serverConnected: PropTypes.bool,
+};
+
+export function ChartContainer(props) {
+  return (
+    <div
+      className="card dashboard-graph"
+      role="object-document"
+      tabIndex="0"
+      aria-labelledby={props.id}
+    >
+      <div className="card-header">
+        <div className="d-flex">
+          <div id={props.id}>{props.title}</div>
+          <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
+        </div>
+      </div>
+      <div className="card-body dashboard-graph-body">
+        <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none' : '')}>
+          {props.children}
+        </div>
+        <ChartError message={props.errorMsg} />
+      </div>
+    </div>
+  );
+}
+
+ChartContainer.propTypes = {
+  id: PropTypes.string.isRequired,
+  title: PropTypes.string.isRequired,
+  legendRef: PropTypes.oneOfType([
+    PropTypes.func,
+    PropTypes.shape({ current: PropTypes.any }),
+  ]).isRequired,
+  children: PropTypes.node.isRequired,
+  errorMsg: PropTypes.string,
+};
+
+export function ChartError(props) {
+  if (props.message === null) {
+    return <></>;
+  }
+  return (
+    <div className="pg-panel-error pg-panel-message" role="alert">
+      {props.message}
+    </div>
+  );
+}
+
+ChartError.propTypes = {
+  message: PropTypes.string,
+};
+
+export function DashboardRow({ children }) {
+  return <div className="row dashboard-row">{children}</div>;
+}
+DashboardRow.propTypes = {
+  children: PropTypes.node.isRequired,
+};
+
+export function DashboardRowCol({ breakpoint, parts, children }) {
+  return <div className={`col-${breakpoint}-${parts}`}>{children}</div>;
+}
+
+DashboardRowCol.propTypes = {
+  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
+  parts: PropTypes.number.isRequired,
+  children: PropTypes.node.isRequired,
+};
diff --git a/web/pgadmin/dashboard/static/js/Graphs.jsx b/web/pgadmin/dashboard/static/js/Graphs.jsx
index cd8fa65a3..69a9af4fc 100644
--- a/web/pgadmin/dashboard/static/js/Graphs.jsx
+++ b/web/pgadmin/dashboard/static/js/Graphs.jsx
@@ -8,7 +8,7 @@
 //////////////////////////////////////////////////////////////
 import React, { useEffect, useRef, useState, useReducer, useCallback, useMemo } from 'react';
 import {LineChart} from 'sources/chartjs';
-import {ChartContainer, DashboardRowCol, DashboardRow} from './dashboard_components';
+import {ChartContainer, DashboardRowCol, DashboardRow} from './Dashboard';
 import url_for from 'sources/url_for';
 import axios from 'axios';
 import gettext from 'sources/gettext';
diff --git a/web/pgadmin/dashboard/static/js/PgAdminLogo.jsx b/web/pgadmin/dashboard/static/js/PgAdminLogo.jsx
new file mode 100644
index 000000000..ecfe6e9e1
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/PgAdminLogo.jsx
@@ -0,0 +1,219 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+
+export default function PgAdminLogo() {
+
+  return (
+    <div className="welcome-logo" aria-hidden="true">
+      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 130">
+        <defs>
+          <style>{'.cls-1{stroke:#000;stroke-width:10.19px;}.cls-2{fill:#336791;}.cls-3,.cls-4,.cls-9{fill:none;}.cls-3,.cls-4,.cls-5,.cls-6{stroke:#fff;}.cls-3,.cls-4{stroke-linecap:round;stroke-width:3.4px;}.cls-3{stroke-linejoin:round;}.cls-4{stroke-linejoin:bevel;}.cls-5,.cls-6{fill:#fff;}.cls-5{stroke-width:1.13px;}.cls-6{stroke-width:0.57px;}.cls-7{fill:#2775b6;}.cls-8{fill:#333;}.cls-9{stroke:#333;stroke-width:3px;}'}</style>
+        </defs>
+        <title>pgAdmin_PostgreSQL</title>
+        <g id="Layer_1" data-name="Layer 1">
+          <g id="Layer_3">
+            <path
+              className="cls-1"
+              d="M95.59,93.65c.77-6.44.54-7.38,5.33-6.34l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21a9,9,0,0,0,.1,2.46c-3.7,4.13-2.62,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.46,1.16,1.36,8.35,1.56,13.48s.55,9.93,1.6,12.75,2.28,10.1,12,8C88.81,119.46,95,117,95.59,93.65"
+            />
+            <path
+              className="cls-2"
+              d="M117.17,79.2c-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21A9.41,9.41,0,0,0,59,80.22c-3.7,4.13-2.61,4.86-10,6.38s-3.08,4.29-.21,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.45,1.16,2.47,7.56,2.3,13.35s-.28,9.77.86,12.88,2.28,10.1,12,8C88.81,119.46,93,115,93.6,107.42,94,102.07,95,102.87,95,98.08l.75-2.26c.87-7.26.14-9.6,5.15-8.51l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31Z"
+            />
+            <path
+              className="cls-3"
+              d="M66.33,83.36c-.38,13.5.09,27.09,1.41,30.39s4.15,9.73,13.88,7.64c8.12-1.74,11.08-5.11,12.36-12.55.94-5.47,2.77-20.67,3-23.79"
+            />
+            <path
+              className="cls-3"
+              d="M54.67,15.7s-44-18-42,22.93c.44,8.7,12.48,65.87,26.84,48.6,5.25-6.32,10-11.27,10-11.27"
+            />
+            <path
+              className="cls-3"
+              d="M78.45,12.42c-1.52.47,24.49-9.51,39.28,9.38,5.22,6.67-.83,33.94-15.31,55.42"
+            />
+            <path
+              className="cls-4"
+              d="M102.42,77.22s.94,4.64,14.65,1.81c6-1.24,2.4,3.48-3.7,6.31-5,2.32-16.21,2.92-16.39-.29-.47-8.27,5.9-5.76,5.44-7.83-.42-1.87-3.26-3.7-5.15-8.27-1.64-4-22.57-34.58,5.8-30,1-.22-7.4-27-33.95-27.42S43.45,44.14,43.45,44.14"
+            />
+            <path
+              className="cls-3"
+              d="M58.9,80.05c-3.7,4.13-2.61,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52,1.66-2.32,0-6-2.28-7-1.1-.46-2.57-1-4.46,1.09Z"
+            />
+            <path
+              className="cls-3"
+              d="M58.66,80c-.38-2.44.79-5.33,2.05-8.71C62.6,66.19,67,61.11,63.47,45c-2.6-12-20-2.5-20-.87a81.48,81.48,0,0,1-.29,16c-1.41,10.06,6.4,18.57,15.39,17.7"
+            />
+            <path
+              className="cls-5"
+              d="M54.51,43.9c-.08.55,1,2,2.45,2.23a2.62,2.62,0,0,0,2.72-1.51c.08-.56-1-1.17-2.44-1.37s-2.65.09-2.73.65Z"
+            />
+            <path
+              className="cls-6"
+              d="M98,42.76c.07.56-1,2-2.45,2.24a2.64,2.64,0,0,1-2.73-1.52c-.07-.55,1-1.16,2.45-1.36s2.65.09,2.73.64Z"
+            />
+            <path
+              className="cls-3"
+              d="M103.07,38.92c.24,4.36-.94,7.33-1.08,12-.22,6.74,3.21,14.46-2,22.19"
+            />
+          </g>
+          <path
+            className="cls-7 app-name"
+            d="M154.72,28.15h5.16v4.16A12.84,12.84,0,0,1,163.35,29a11.17,11.17,0,0,1,6.28-1.76,11.84,11.84,0,0,1,9.08,4.09c2.48,2.72,3.73,6.62,3.73,11.67q0,10.26-5.38,14.65a12.2,12.2,0,0,1-7.95,2.79,10.78,10.78,0,0,1-6-1.56,13.55,13.55,0,0,1-3.14-3v16h-5.28Zm19.84,24.6Q177,49.65,177,43.5a17,17,0,0,0-1.09-6.44,7.51,7.51,0,0,0-7.53-5.19q-5.49,0-7.52,5.48a21.49,21.49,0,0,0-1.09,7.44A15.64,15.64,0,0,0,160.88,51a8,8,0,0,0,13.68,1.78Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M206,29.26a14.6,14.6,0,0,1,3,3V28.3h4.86V56.83c0,4-.58,7.13-1.75,9.44q-3.27,6.38-12.35,6.38a15.07,15.07,0,0,1-8.5-2.27,8.86,8.86,0,0,1-3.85-7.1h5.36a6,6,0,0,0,1.52,3.25q1.77,1.75,5.59,1.76,6,0,7.9-4.28,1.1-2.52,1-9a10.39,10.39,0,0,1-3.8,3.57,13.56,13.56,0,0,1-14.75-2.45q-3.81-3.62-3.81-12,0-7.89,3.84-12.31a11.85,11.85,0,0,1,9.27-4.42A11.37,11.37,0,0,1,206,29.26Zm.64,5.66a7.61,7.61,0,0,0-6.09-2.81A7.52,7.52,0,0,0,193,37.32a20.56,20.56,0,0,0-1.08,7.3c0,3.53.72,6.22,2.14,8.07a6.93,6.93,0,0,0,5.76,2.77,8.09,8.09,0,0,0,8-5.13A16.72,16.72,0,0,0,209,43.56Q209,37.73,206.62,34.92Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M235.16,16.34h6.58l15.62,43H251l-4.5-12.89H229.6l-4.67,12.89h-6Zm9.67,25.4-6.63-19-6.88,19Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M279.16,29a14.3,14.3,0,0,1,3.18,3.08V16.2h5.07V59.38h-4.75V55a11.33,11.33,0,0,1-4.35,4.19,12.51,12.51,0,0,1-5.75,1.28,11.61,11.61,0,0,1-9-4.4q-3.82-4.41-3.83-11.74a20.35,20.35,0,0,1,3.49-11.88,11.41,11.41,0,0,1,10-5A11.15,11.15,0,0,1,279.16,29ZM267.39,52.5q2.13,3.39,6.82,3.39a7.17,7.17,0,0,0,6-3.14c1.56-2.1,2.35-5.12,2.35-9s-.81-6.9-2.42-8.81a7.56,7.56,0,0,0-6-2.85,7.88,7.88,0,0,0-6.43,3c-1.64,2-2.46,5-2.46,9A15.62,15.62,0,0,0,267.39,52.5Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M295.29,28h5.21v4.46a17.4,17.4,0,0,1,3.4-3.37,10.24,10.24,0,0,1,5.92-1.79,9.34,9.34,0,0,1,6,1.85,9.61,9.61,0,0,1,2.34,3.1,11.37,11.37,0,0,1,4.13-3.73,11.52,11.52,0,0,1,5.33-1.22q6.33,0,8.62,4.57a15,15,0,0,1,1.23,6.62V59.38H332V37.58c0-2.09-.52-3.52-1.57-4.3a6.2,6.2,0,0,0-3.82-1.17,7.58,7.58,0,0,0-5.35,2.08c-1.49,1.38-2.24,3.7-2.24,6.94V59.38h-5.36V38.9a10.78,10.78,0,0,0-.76-4.66q-1.2-2.19-4.49-2.19A7.73,7.73,0,0,0,303,34.36c-1.63,1.54-2.45,4.34-2.45,8.38V59.38h-5.27Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M345.27,16.34h5.36v6h-5.36Zm0,11.81h5.36V59.38h-5.36Z"
+          />
+          <path
+            className="cls-7 app-name"
+            d="M358.6,28h5v4.46a14,14,0,0,1,4.72-4,12.56,12.56,0,0,1,5.53-1.2c4.46,0,7.46,1.55,9,4.66a16.52,16.52,0,0,1,1.29,7.29V59.38h-5.37V39.61A10.8,10.8,0,0,0,378,35a5.15,5.15,0,0,0-5.1-2.93,10.21,10.21,0,0,0-3.08.38A8,8,0,0,0,366,35a7.66,7.66,0,0,0-1.71,3.2,21.84,21.84,0,0,0-.4,4.74V59.38H358.6Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M155.24,86.87h3.9l5.77,17,5.74-17h3.87V107h-2.6V95.1q0-.61,0-2c0-.94,0-2,0-3L166.24,107h-2.7L157.75,90v.61c0,.49,0,1.24,0,2.25s.05,1.75.05,2.22V107h-2.6Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M186.15,98.09a1.35,1.35,0,0,0,1.14-.71,2.31,2.31,0,0,0,.16-.94,2,2,0,0,0-.89-1.84A4.79,4.79,0,0,0,184,94a3.21,3.21,0,0,0-2.73,1,3.44,3.44,0,0,0-.59,1.72h-2.3A4.28,4.28,0,0,1,180.14,93,7.16,7.16,0,0,1,184.05,92a8,8,0,0,1,4.19,1,3.34,3.34,0,0,1,1.6,3.06v8.44a1.06,1.06,0,0,0,.16.62.77.77,0,0,0,.66.23l.37,0,.44-.07V107a7.38,7.38,0,0,1-.88.21,5.92,5.92,0,0,1-.82,0,2,2,0,0,1-1.84-.9,3.63,3.63,0,0,1-.43-1.36,6.16,6.16,0,0,1-2.16,1.71,6.56,6.56,0,0,1-3.1.73,4.59,4.59,0,0,1-3.33-1.24,4.09,4.09,0,0,1-1.29-3.09,4,4,0,0,1,1.27-3.16,6.16,6.16,0,0,1,3.34-1.38ZM181,104.74a2.88,2.88,0,0,0,1.84.62,5.51,5.51,0,0,0,2.52-.61,3.37,3.37,0,0,0,2-3.26v-2a3.79,3.79,0,0,1-1.16.48,10.37,10.37,0,0,1-1.39.28l-1.49.19a5.68,5.68,0,0,0-2,.56,2.18,2.18,0,0,0-1.14,2A2,2,0,0,0,181,104.74Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M193.88,92.31h2.33v2.08a6.73,6.73,0,0,1,2.2-1.85A6,6,0,0,1,201,92q3.12,0,4.21,2.18a7.73,7.73,0,0,1,.6,3.4V107h-2.5V97.73a4.87,4.87,0,0,0-.4-2.16,2.41,2.41,0,0,0-2.38-1.37,4.75,4.75,0,0,0-1.43.18,3.68,3.68,0,0,0-1.78,1.2,3.55,3.55,0,0,0-.8,1.5,10.3,10.3,0,0,0-.18,2.21V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M217.29,98.09a1.33,1.33,0,0,0,1.14-.71,2.15,2.15,0,0,0,.16-.94,2,2,0,0,0-.89-1.84,4.79,4.79,0,0,0-2.56-.56,3.24,3.24,0,0,0-2.73,1,3.44,3.44,0,0,0-.58,1.72h-2.3A4.27,4.27,0,0,1,211.28,93,7.19,7.19,0,0,1,215.2,92a8,8,0,0,1,4.19,1A3.36,3.36,0,0,1,221,96v8.44a1.14,1.14,0,0,0,.15.62.79.79,0,0,0,.67.23l.37,0,.43-.07V107a7.32,7.32,0,0,1-.87.21,6,6,0,0,1-.82,0,2,2,0,0,1-1.85-.9,3.46,3.46,0,0,1-.42-1.36,6.16,6.16,0,0,1-2.16,1.71,6.63,6.63,0,0,1-3.11.73,4.58,4.58,0,0,1-3.32-1.24,4.06,4.06,0,0,1-1.3-3.09A4,4,0,0,1,210,100a6.13,6.13,0,0,1,3.33-1.38Zm-5.18,6.65a2.91,2.91,0,0,0,1.85.62,5.47,5.47,0,0,0,2.51-.61,3.38,3.38,0,0,0,2.06-3.26v-2a3.9,3.9,0,0,1-1.16.48,10.51,10.51,0,0,1-1.4.28l-1.48.19a5.55,5.55,0,0,0-2,.56,2.17,2.17,0,0,0-1.15,2A2,2,0,0,0,212.11,104.74Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M233.16,92.9a7.05,7.05,0,0,1,1.42,1.39V92.45h2.27v13.32a10,10,0,0,1-.82,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.15,4.15,0,0,1-1.8-3.32H227a2.81,2.81,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.88,0,3.1-.66,3.68-2a11.15,11.15,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,5.93,5.93,0,0,1-2.74.54,5.79,5.79,0,0,1-4.14-1.69q-1.79-1.68-1.78-5.58a8.49,8.49,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.33,5.33,0,0,1,233.16,92.9Zm.3,2.64a3.77,3.77,0,0,0-6.38,1.12,9.73,9.73,0,0,0-.5,3.4,6.05,6.05,0,0,0,1,3.77,3.21,3.21,0,0,0,2.68,1.29,3.77,3.77,0,0,0,3.72-2.39,7.71,7.71,0,0,0,.6-3.16A6.13,6.13,0,0,0,233.46,95.54Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M249.64,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,17.44,17.44,0,0,1,.22,3.23H242.4a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3.05-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.58,6.58,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.71,8.71,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,249.64,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M256.16,92.31h2.44v2.08a8.23,8.23,0,0,1,1.58-1.57A4.79,4.79,0,0,1,263,92a4.31,4.31,0,0,1,2.81.87,4.5,4.5,0,0,1,1.1,1.44,5.27,5.27,0,0,1,1.92-1.74,5.37,5.37,0,0,1,2.49-.57,4.08,4.08,0,0,1,4,2.14,7,7,0,0,1,.58,3.09V107h-2.56V96.78a2.41,2.41,0,0,0-.73-2,2.93,2.93,0,0,0-1.79-.54,3.53,3.53,0,0,0-2.49,1,4.23,4.23,0,0,0-1.05,3.24V107h-2.5V97.4a5,5,0,0,0-.36-2.18,2.17,2.17,0,0,0-2.09-1,3.59,3.59,0,0,0-2.53,1.08c-.76.72-1.14,2-1.14,3.91V107h-2.47Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M288.53,92.72a5.47,5.47,0,0,1,2.22,1.89,6.67,6.67,0,0,1,1,2.58,17.66,17.66,0,0,1,.21,3.23H281.29a6.42,6.42,0,0,0,1,3.59,3.48,3.48,0,0,0,3,1.35,3.9,3.9,0,0,0,3.06-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5.23,5.23,0,0,1-.64,1.8,6.56,6.56,0,0,1-1.2,1.62,5.7,5.7,0,0,1-2.76,1.48,8.62,8.62,0,0,1-2,.21,6.14,6.14,0,0,1-4.61-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.91-5.72,6.24,6.24,0,0,1,5-2.21A6.58,6.58,0,0,1,288.53,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.53,3.53,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.63,4.63,0,0,0-1.2,3.11Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M295.06,92.31h2.34v2.08a6.63,6.63,0,0,1,2.2-1.85,5.91,5.91,0,0,1,2.58-.56c2.08,0,3.49.73,4.21,2.18a7.57,7.57,0,0,1,.61,3.4V107h-2.51V97.73a5,5,0,0,0-.39-2.16,2.41,2.41,0,0,0-2.38-1.37,4.86,4.86,0,0,0-1.44.18,3.7,3.7,0,0,0-1.77,1.2,3.55,3.55,0,0,0-.8,1.5,9.58,9.58,0,0,0-.19,2.21V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M311.13,88.22h2.48v4.09H316v2h-2.34v9.56a1,1,0,0,0,.52,1,2.21,2.21,0,0,0,1,.15h.38l.48,0v2a4.16,4.16,0,0,1-.88.18,7.74,7.74,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88,3.94,3.94,0,0,1-.61-2.29v-9.7h-2v-2h2Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M340.63,86.87v2.39h-6.77V107h-2.75V89.26h-6.76V86.87Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M350.31,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2A8.08,8.08,0,0,1,338.7,100a8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.6,6.6,0,0,1,350.31,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.49,3.49,0,0,0-3.25,1.72,8.07,8.07,0,0,0-1,4.15,7.05,7.05,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.35,3.35,0,0,0,348.78,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M365.88,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2,8.08,8.08,0,0,1-1.77-5.48,8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,365.88,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.46,3.46,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.54,3.54,0,0,0,3.21,1.56A3.35,3.35,0,0,0,364.35,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M370.91,86.87h2.46V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M378.53,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.86,4.86,0,0,0,2.45-.6A2,2,0,0,0,386,103a1.56,1.56,0,0,0-.84-1.43,10.63,10.63,0,0,0-2.14-.7l-2-.49a10,10,0,0,1-2.81-1,3.11,3.11,0,0,1-1.61-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.83,1.94a4.24,4.24,0,0,1,.91,2.65h-2.33A2.72,2.72,0,0,0,385,95a3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.65,1.65,0,0,0-.74,1.4,1.73,1.73,0,0,0,1,1.53,5.69,5.69,0,0,0,1.64.6l1.66.4A12.73,12.73,0,0,1,387,99.75a3.3,3.3,0,0,1,1.44,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43c-2.2,0-3.77-.5-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M400,87.84c.58-.84,1.68-1.26,3.32-1.26l.48,0,.56,0v2.24l-.56,0h-.32c-.76,0-1.21.19-1.36.58a11.75,11.75,0,0,0-.22,3h2.46v1.94h-2.46V107h-2.43V94.32h-2V92.38h2v-2.3A4.43,4.43,0,0,1,400,87.84Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M417.23,93.77a7.38,7.38,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.18,6.18,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2,8.07,8.07,0,0,1-1.76-5.48,8.83,8.83,0,0,1,1.85-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,417.23,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.47,3.47,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.55,3.55,0,0,0,3.22,1.56A3.35,3.35,0,0,0,415.7,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M422.26,92.31h2.34v2.53A5.61,5.61,0,0,1,426,93,3.68,3.68,0,0,1,428.59,92l.24,0,.56,0v2.6a2.08,2.08,0,0,0-.41-.05l-.4,0a3.52,3.52,0,0,0-2.86,1.2,4.2,4.2,0,0,0-1,2.75V107h-2.46Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M439.89,86.87h9a6.09,6.09,0,0,1,4.31,1.51,5.5,5.5,0,0,1,1.64,4.25,6.15,6.15,0,0,1-1.47,4.09,5.5,5.5,0,0,1-4.47,1.74h-6.27V107h-2.72Zm10.55,2.76a5.92,5.92,0,0,0-2.46-.42h-5.37v7H448a5.07,5.07,0,0,0,2.95-.78,3.1,3.1,0,0,0,1.14-2.75A3,3,0,0,0,450.44,89.63Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M468.58,93.77a7.38,7.38,0,0,1,1.95,5.55,9.51,9.51,0,0,1-1.72,5.85,6.17,6.17,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2A8.07,8.07,0,0,1,457,100a8.78,8.78,0,0,1,1.86-5.88,6.23,6.23,0,0,1,5-2.18A6.56,6.56,0,0,1,468.58,93.77Zm-1.52,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.65,3.65,0,0,0-3.55-2,3.48,3.48,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.36,3.36,0,0,0,467.06,103.51Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M475,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.93,4.93,0,0,0,2.46-.6,2,2,0,0,0,1.06-1.84,1.55,1.55,0,0,0-.85-1.43,10.4,10.4,0,0,0-2.14-.7l-2-.49a9.78,9.78,0,0,1-2.8-1,3.1,3.1,0,0,1-1.62-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.84,1.94a4.17,4.17,0,0,1,.9,2.65h-2.33a2.72,2.72,0,0,0-.6-1.51,3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.64,1.64,0,0,0-.73,1.4,1.72,1.72,0,0,0,1,1.53,5.66,5.66,0,0,0,1.65.6l1.65.4a12.83,12.83,0,0,1,3.63,1.24,3.31,3.31,0,0,1,1.43,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43q-3.3,0-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M488,88.22h2.49v4.09h2.34v2h-2.34v9.56a1,1,0,0,0,.52,1,2.19,2.19,0,0,0,.95.15h.39l.48,0v2a4.39,4.39,0,0,1-.89.18,7.52,7.52,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88A3.94,3.94,0,0,1,488,104v-9.7h-2v-2h2Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M503.47,92.9a6.78,6.78,0,0,1,1.41,1.39V92.45h2.27v13.32a10,10,0,0,1-.81,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.1,4.1,0,0,1-1.8-3.32h2.5a2.74,2.74,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.87,0,3.1-.66,3.68-2a11.37,11.37,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,6,6,0,0,1-2.74.54,5.83,5.83,0,0,1-4.15-1.69q-1.77-1.68-1.77-5.58a8.43,8.43,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.38,5.38,0,0,1,503.47,92.9Zm.3,2.64a3.56,3.56,0,0,0-2.85-1.31,3.5,3.5,0,0,0-3.53,2.43,9.48,9.48,0,0,0-.51,3.4,6.12,6.12,0,0,0,1,3.77,3.24,3.24,0,0,0,2.69,1.29,3.75,3.75,0,0,0,3.71-2.39,7.71,7.71,0,0,0,.6-3.16A6.14,6.14,0,0,0,503.77,95.54Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M511,92.31h2.33v2.53a5.91,5.91,0,0,1,1.41-1.8A3.69,3.69,0,0,1,517.3,92l.23,0,.56,0v2.6a2.08,2.08,0,0,0-.4-.05l-.41,0a3.48,3.48,0,0,0-2.85,1.2,4.14,4.14,0,0,0-1,2.75V107H511Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M529.27,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,16.6,16.6,0,0,1,.22,3.23H522a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3-1.28,4.37,4.37,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.34,6.34,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.65,8.65,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,529.27,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M537.9,100.47a5.6,5.6,0,0,0,.78,2.78q1.3,2,4.59,2a7.9,7.9,0,0,0,2.69-.44,3.09,3.09,0,0,0,2.34-3,2.64,2.64,0,0,0-1-2.33,9.55,9.55,0,0,0-3.15-1.19l-2.64-.62a11.41,11.41,0,0,1-3.65-1.33A4.23,4.23,0,0,1,536,92.54a5.86,5.86,0,0,1,1.83-4.44A7.16,7.16,0,0,1,543,86.37a8.75,8.75,0,0,1,5.22,1.52,5.57,5.57,0,0,1,2.15,4.87h-2.56a5.12,5.12,0,0,0-.84-2.47c-.79-1.05-2.14-1.57-4.05-1.57a4.51,4.51,0,0,0-3.31,1,3.2,3.2,0,0,0-1,2.35,2.33,2.33,0,0,0,1.19,2.16,16.76,16.76,0,0,0,3.54,1.09l2.73.65a8.15,8.15,0,0,1,3,1.27,4.81,4.81,0,0,1,1.86,4.09,5.14,5.14,0,0,1-2.37,4.77,10.46,10.46,0,0,1-5.5,1.43,8.07,8.07,0,0,1-5.72-1.91,6.57,6.57,0,0,1-2-5.16Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M573.17,106.9l-1.36,1.65-3.11-2.36a11.33,11.33,0,0,1-2.43,1,10.29,10.29,0,0,1-2.85.37,9.18,9.18,0,0,1-7.32-3.06A11.71,11.71,0,0,1,553.76,97a11.9,11.9,0,0,1,2-7,8.78,8.78,0,0,1,7.69-3.72c3.54,0,6.17,1.14,7.87,3.42a11.08,11.08,0,0,1,2,6.82,14.28,14.28,0,0,1-.48,3.73,9.67,9.67,0,0,1-2.44,4.46ZM565.35,105a3.36,3.36,0,0,0,1.29-.47l-2.22-1.72,1.37-1.68,2.62,2A7.5,7.5,0,0,0,570.1,100a13.76,13.76,0,0,0,.45-3.39,8.48,8.48,0,0,0-1.85-5.7,6.35,6.35,0,0,0-5.07-2.17,6.6,6.6,0,0,0-5.15,2.08q-1.9,2.07-1.9,6.38A8.64,8.64,0,0,0,558.4,103a6.63,6.63,0,0,0,5.36,2.15A11.24,11.24,0,0,0,565.35,105Z"
+          />
+          <path
+            className="cls-8 app-tagline"
+            d="M576.58,86.87h2.72v17.69h10.08V107h-12.8Z"
+          />
+          <line
+            className="cls-9 app-name-underline"
+            x1="219.17"
+            y1="66.5"
+            x2="384.17"
+            y2="66.5"
+          />
+        </g>
+      </svg>
+    </div>);
+
+
+}
diff --git a/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
new file mode 100644
index 000000000..ea4b58003
--- /dev/null
+++ b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
@@ -0,0 +1,249 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React from 'react';
+import gettext from 'sources/gettext';
+import _ from 'lodash';
+import { Link, BrowserRouter } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import { makeStyles } from '@material-ui/core/styles';
+import pgAdmin from 'sources/pgadmin';
+import PgAdminLogo from './PgAdminLogo';
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    background: theme.palette.grey[400],
+    overflow: 'hidden',
+    padding: '8px',
+    display: 'flex',
+    flexDirection: 'column',
+    flexGrow: 1,
+    height: '100%'
+
+  },
+  dashboardContainer: {
+    paddingBottom: '8px',
+    minHeight: '100%'
+  },
+  card: {
+    position: 'relative',
+    minWidth: 0,
+    wordWrap: 'break-word',
+    backgroundColor: theme.otherVars.tableBg,
+    backgroundClip: 'border-box',
+    border: '1px solid' + theme.otherVars.borderColor,
+    borderRadius: theme.shape.borderRadius,
+    marginTop: 8
+  },
+  row: {
+    marginRight: '-8px',
+    marginLeft: '-8px'
+  },
+  rowContent: {
+    display: 'flex',
+    flexWrap: 'wrap',
+    marginRight: '-7.5px',
+    marginLeft: '-7.5px'
+  },
+  cardHeader: {
+    padding: '0.25rem 0.5rem',
+    fontWeight: 'bold',
+    backgroundColor: theme.otherVars.tableBg,
+    borderBottom: '1px solid',
+    borderBottomColor: theme.otherVars.borderColor,
+  },
+  dashboardLink: {
+    color: theme.otherVars.colorFg + '!important',
+    flex: '0 0 50%',
+    maxWidth: '50%',
+    textAlign: 'center',
+    cursor: 'pointer'
+  },
+  gettingStartedLink: {
+    flex: '0 0 25%',
+    maxWidth: '50%',
+    textAlign: 'center',
+    cursor: 'pointer'
+  },
+  link: {
+    color: theme.otherVars.colorFg + '!important',
+  },
+  cardColumn: {
+    flex: '0 0 100%',
+    maxWidth: '100%',
+    margin: '8px'
+  },
+  cardBody: {
+    flex: '1 1 auto',
+    minHeight: '1px',
+    padding: '0.5rem !important',
+  }
+}));
+
+
+function AddNewServer(pgBrowser) {
+  if (pgBrowser && pgBrowser.tree) {
+    var i = _.isUndefined(pgBrowser.tree.selected()) ?
+        pgBrowser.tree.first(null, false) :
+        pgBrowser.tree.selected(),
+      serverModule = pgAdmin.Browser.Nodes.server,
+      itemData = pgBrowser.tree.itemData(i);
+
+    while (itemData && itemData._type != 'server_group') {
+      i = pgBrowser.tree.next(i);
+      itemData = pgBrowser.tree.itemData(i);
+    }
+
+    if (!itemData) {
+      return;
+    }
+
+    if (serverModule) {
+      serverModule.callbacks.show_obj_properties.apply(
+        serverModule, [{
+          action: 'create',
+        }, i]
+      );
+    }
+  }
+}
+
+export default function WelcomeDashboard({ pgBrowser }) {
+
+  const classes = useStyles();
+
+  return (
+    <BrowserRouter>
+      <div className={classes.emptyPanel}>
+        <div className={classes.dashboardContainer}>
+          <div className={classes.row}>
+            <div className={classes.cardColumn}>
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Welcome')}</div>
+                <div className={classes.cardBody}>
+                  <PgAdminLogo />
+                  <h4>
+                    {gettext('Feature rich')} | {gettext('Maximises PostgreSQL')}{' '}
+                    | {gettext('Open Source')}{' '}
+                  </h4>
+                  <p>
+                    {gettext(
+                      'pgAdmin is an Open Source administration and management tool for the PostgreSQL database. It includes a graphical administration interface, an SQL query tool, a procedural code debugger and much more. The tool is designed to answer the needs of developers, DBAs and system administrators alike.'
+                    )}
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className={classes.row}>
+            <div className={classes.cardColumn}>
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Quick Links')}</div>
+                <div className={classes.cardBody}>
+                  <div className={classes.rowContent}>
+                    <div className={classes.dashboardLink}>
+                      <Link to="#" onClick={() => { AddNewServer(pgBrowser); }} className={classes.link}>
+                        <span
+                          className="fa fa-4x dashboard-icon fa-server"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Add New Server')}
+                      </Link>
+                    </div>
+                    <div className={classes.dashboardLink}>
+                      <Link to="#" onClick={() => pgAdmin.Preferences.show()} className={classes.link}>
+                        <span
+                          id="mnu_preferences"
+                          className="fa fa-4x dashboard-icon fa-cogs"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Configure pgAdmin')}
+                      </Link>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className={classes.row}>
+            <div className={classes.cardColumn}>
+              <div className={classes.card}>
+                <div className={classes.cardHeader}>{gettext('Getting Started')}</div>
+                <div className={classes.cardBody}>
+                  <div className={classes.rowContent}>
+                    <div className={classes.gettingStartedLink}>
+                      <a
+                        href="http://www.postgresql.org/docs"
+                        target="postgres_help"
+                        className={classes.link}
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon dashboard-pg-doc"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('PostgreSQL Documentation')}
+                      </a>
+                    </div>
+                    <div className={classes.gettingStartedLink}>
+                      <a href="https://www.pgadmin.org" target="pgadmin_website" className={classes.link}>
+                        <span
+                          className="fa fa-4x dashboard-icon fa-globe"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('pgAdmin Website')}
+                      </a>
+                    </div>
+                    <div className={classes.gettingStartedLink}>
+                      <a
+                        href="http://planet.postgresql.org"
+                        target="planet_website"
+                        className={classes.link}
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon fa-book"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Planet PostgreSQL')}
+                      </a>
+                    </div>
+                    <div className={classes.gettingStartedLink}>
+                      <a
+                        href="http://www.postgresql.org/community"
+                        target="postgres_website"
+                        className={classes.link}
+                      >
+                        <span
+                          className="fa fa-4x dashboard-icon fa-users"
+                          aria-hidden="true"
+                        ></span>
+                        <br />
+                        {gettext('Community Support')}
+                      </a>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </BrowserRouter>
+  );
+}
+
+
+WelcomeDashboard.propTypes = {
+  pgBrowser: PropTypes.object.isRequired
+};
+
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
deleted file mode 100644
index 258071da4..000000000
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ /dev/null
@@ -1,1209 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import Notify from '../../../static/js/helpers/Notifier';
-
-define('pgadmin.dashboard', [
-  'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
-  'sources/pgadmin', 'backbone', 'backgrid',
-  'pgadmin.alertifyjs', 'pgadmin.backform', 'sources/nodes/dashboard',
-  'sources/window', './ChartsDOM', 'pgadmin.browser', 'bootstrap', 'wcdocker',
-], function(
-  url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid,
-  Alertify, Backform, NodesDashboard, pgWindow, ChartsDOM
-) {
-
-  pgAdmin.Browser = pgAdmin.Browser || {};
-  var pgBrowser = pgAdmin.Browser;
-
-  /* Return back, this has been called more than once */
-  if (pgAdmin.Dashboard)
-    return;
-
-  var dashboardVisible = true,
-    cancel_query_url = '',
-    terminate_session_url = '',
-    is_super_user = false,
-    current_user, maintenance_database,
-    is_server_dashboard = false,
-    is_database_dashboard = false,
-    can_signal_backend = false;
-
-  // Custom BackGrid cell, Responsible for cancelling active sessions
-  var customDashboardActionCell = Backgrid.Extension.DeleteCell.extend({
-    render: function() {
-      this.$el.empty();
-      var self = this,
-        cell_action = self.column.get('cell_action');
-      // if cancel query button then
-      if (cell_action === 'cancel') {
-        this.$el.html(
-          '<i class=\'fa fa-stop\' data-toggle=\'tooltip\' ' +
-          'title=\'' + gettext('Cancel the active query') +
-          '\' aria-label=\''+ gettext('Cancel the active query') +'\'></i>'
-        );
-      } else {
-        this.$el.html(
-          '<i class=\'fa fa-times-circle text-danger\' data-toggle=\'tooltip\' ' +
-          'title=\'' + gettext('Terminate the session') +
-          '\' aria-label=\''+ gettext('Terminate the session') +'\'></i>'
-        );
-      }
-      this.$el.attr('tabindex', 0);
-      this.$el.on('keydown', function(e) {
-        // terminating session or cancel the active query.
-        if (e.keyCode == 32) {
-          self.$el.click();
-        }
-      });
-      this.delegateEvents();
-      return this;
-    },
-    deleteRow: function(e) {
-      var self = this,
-        title, txtConfirm, txtSuccess, txtError, action_url,
-        cell_action = self.column.get('cell_action');
-
-      e.preventDefault();
-
-      var canDeleteRow = Backgrid.callByNeed(
-        self.column.get('canDeleteRow'), self.column, self.model
-      );
-      // If we are not allowed to cancel the query, return from here
-      if (!canDeleteRow)
-        return;
-
-      // This will refresh the grid
-      let refresh_grid = () => {
-        $('#btn_refresh').trigger('click');
-      };
-
-      if (cell_action === 'cancel') {
-        title = gettext('Cancel Active Query?');
-        txtConfirm = gettext('Are you sure you wish to cancel the active query?');
-        txtSuccess = gettext('Active query cancelled successfully.');
-        txtError = gettext('An error occurred whilst cancelling the active query.');
-        action_url = cancel_query_url + self.model.get('pid');
-      } else {
-        title = gettext('Terminate Session?');
-        txtConfirm = gettext('Are you sure you wish to terminate the session?');
-        txtSuccess = gettext('Session terminated successfully.');
-        txtError = gettext('An error occurred whilst terminating the active query.');
-        action_url = terminate_session_url + self.model.get('pid');
-      }
-
-      Notify.confirm(
-        title, txtConfirm,
-        function() {
-          $.ajax({
-            url: action_url,
-            type: 'DELETE',
-          })
-            .done(function(res) {
-              if (res == gettext('Success')) {
-                Notify.success(txtSuccess);
-                refresh_grid();
-              } else {
-                Notify.error(txtError);
-              }
-            })
-            .fail(function(xhr, status, error) {
-              Notify.pgRespErrorNotify(xhr, error);
-            });
-        },
-        function() {
-          return true;
-        }
-      );
-    },
-  });
-
-
-  // Subnode Cell, which will display subnode control
-  var SessionDetailsCell = Backgrid.Extension.ObjectCell.extend({
-    enterEditMode: function() {
-      // Notify that we are about to enter in edit mode for current cell.
-      this.model.trigger('enteringEditMode', [this]);
-
-      Backgrid.Cell.prototype.enterEditMode.apply(this, arguments);
-      /* Make sure - we listen to the click event */
-      this.delegateEvents();
-      var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model);
-
-      if (editable) {
-        this.$el.html(
-          '<i class=\'fa fa-caret-down subnode-edit-in-process\'></i>'
-        );
-        this.model.trigger(
-          'pg-sub-node:opened', this.model, this
-        );
-      }
-    },
-    render: function() {
-      this.$el.empty();
-      this.$el.html(
-        '<i class=\'fa fa-caret-right\' data-toggle=\'tooltip\' ' +
-        'title=\'' + gettext('View the active session details') +
-        '\' aria-label=\''+ gettext('View the active session details') +'\'></i>'
-      );
-      this.delegateEvents();
-      if (this.grabFocus)
-        this.$el.trigger('focus');
-      return this;
-    },
-  });
-
-  // Subnode Model
-  var ActiveQueryDetailsModel = Backbone.Model.extend({
-    defaults: {
-      version: null,
-      /* Postgres version */
-    },
-    schema: [{
-      id: 'backend_type',
-      label: gettext('Backend type'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      group: gettext('Details'),
-      visible: function() {
-        return this.version >= 100000;
-      },
-    }, {
-      id: 'query_start',
-      label: gettext('Query started at'),
-      type: 'text',
-      editable: false,
-      readonly: true,
-      group: gettext('Details'),
-    }, {
-      id: 'state_change',
-      label: gettext('Last state changed at'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      group: gettext('Details'),
-    }, {
-      id: 'query',
-      label: gettext('SQL'),
-      type: 'text',
-      editable: true,
-      readonly: true,
-      control: Backform.SqlFieldControl,
-      group: gettext('Details'),
-    }],
-  });
-
-  pgAdmin.Dashboard = {
-    init: function() {
-      if (this.initialized)
-        return;
-
-      this.initialized = true;
-      this.chartsDomObj = null;
-
-      this.sid = this.did = -1;
-      this.version = -1;
-
-
-      // Bind the Dashboard object with the 'object_selected' function
-      var selected = this.object_selected.bind(this);
-      var disconnected = this.object_disconnected.bind(this);
-
-      // Listen for selection of any of object
-      pgBrowser.Events.on('pgadmin-browser:tree:selected', selected);
-
-      // Listen for server disconnected event
-      pgBrowser.Events.on('pgadmin:server:disconnect', disconnected);
-
-      // Load the default welcome dashboard
-      var url = url_for('dashboard.index');
-
-      var dashboardPanel = pgBrowser.panels['dashboard'].panel;
-      if (dashboardPanel) {
-        var div = dashboardPanel.layout().scene().find('.pg-panel-content');
-        if (div) {
-          var ajaxHook = function() {
-            $.ajax({
-              url: url,
-              type: 'GET',
-              dataType: 'html',
-            })
-              .done(function(data) {
-                $(div).html(data);
-              })
-              .fail(function(xhr, error) {
-                self.onFail(xhr, error, div, ajaxHook);
-              });
-          };
-          $(div).html(
-            '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
-          );
-          ajaxHook();
-
-          // Cache the current IDs for next time
-          $(dashboardPanel).data('sid', -1);
-          $(dashboardPanel).data('did', -1);
-        }
-      }
-    },
-
-    onFail: function(xhr, error, div, ajaxHook) {
-      Notify.pgNotifier(
-        error, xhr,
-        gettext('An error occurred whilst loading the dashboard.'),
-        function(msg) {
-          if(msg === 'CRYPTKEY_SET') {
-            ajaxHook();
-          } else {
-            $(div).html(
-              '<div class="pg-panel-message" role="alert">' + gettext('An error occurred whilst loading the dashboard.') + '</div>'
-            );
-          }
-        }
-      );
-    },
-
-    // Handle Server Disconnect
-    object_disconnected: function() {
-      let item = pgBrowser.tree.selected(),
-        itemData = item && pgBrowser.tree.itemData(item);
-
-      // The server connected may not be the same one, which was selected, and
-      // we do care out the current selected one only.
-      if (item.length != 0) {
-        this.object_selected(item, itemData);
-      }
-    },
-
-    // Handle treeview clicks
-    object_selected: function(item, itemData) {
-      let self = this;
-
-      if (itemData && itemData._type) {
-        var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
-          url = NodesDashboard.url(itemData, item, treeHierarchy);
-
-        if (url === null) {
-          url = url_for('dashboard.index');
-          self.version = (treeHierarchy.server && treeHierarchy.server.version) || 0;
-
-          cancel_query_url = url + 'cancel_query/';
-          terminate_session_url = url + 'terminate_session/';
-
-          // Check if user is super user
-          var server = treeHierarchy['server'];
-          maintenance_database = (server && server.db) || null;
-          can_signal_backend = (server && server.user) ? server.user.can_signal_backend : false;
-
-          if (server && server.user && server.user.is_superuser) {
-            is_super_user = true;
-          } else {
-            is_super_user = false;
-            // Set current user
-            current_user = (server && server.user) ? server.user.name : null;
-          }
-
-          if ('database' in treeHierarchy) {
-            self.sid = treeHierarchy.server._id;
-            self.did = treeHierarchy.database._id;
-            is_server_dashboard = false;
-            is_database_dashboard = true;
-            url += self.sid + '/' + self.did;
-            cancel_query_url += self.sid + '/' + self.did + '/';
-            terminate_session_url += self.sid + '/' + self.did + '/';
-          } else if ('server' in treeHierarchy) {
-            self.sid = treeHierarchy.server._id;
-            self.did = -1;
-            is_server_dashboard = true;
-            is_database_dashboard = false;
-            url += self.sid;
-            cancel_query_url += self.sid + '/';
-            terminate_session_url += self.sid + '/';
-          } else {
-            is_server_dashboard = is_database_dashboard = false;
-          }
-        } else {
-          is_server_dashboard = is_database_dashboard = false;
-        }
-
-        var dashboardPanel = pgBrowser.panels['dashboard'].panel;
-        if (dashboardPanel) {
-          var div = dashboardPanel.layout().scene().find(
-            '.pg-panel-content'
-          );
-
-          if (div) {
-            if (itemData.connected || _.isUndefined(itemData.connected)) {
-              // Avoid unnecessary reloads
-              if (
-                url !== $(dashboardPanel).data('dashboard_url') || (
-                  url === $(dashboardPanel).data('dashboard_url') &&
-                  $(dashboardPanel).data('server_status') == false
-                )
-              ) {
-                this.chartsDomObj && this.chartsDomObj.unmount();
-                $(div).empty();
-
-                let ajaxHook = function() {
-                  $.ajax({
-                    url: url,
-                    type: 'GET',
-                    dataType: 'html',
-                  })
-                    .done(function(data) {
-                      $(div).html(data);
-                      self.init_dashboard();
-                    })
-                    .fail(function(xhr, error) {
-                      self.onFail(xhr, error, div, ajaxHook);
-                    });
-                };
-                $(div).html(
-                  '<div class="pg-panel-message" role="alert">' + gettext('Loading dashboard...') + '</div>'
-                );
-                ajaxHook();
-                $(dashboardPanel).data('server_status', true);
-              }
-            } else {
-              this.chartsDomObj && this.chartsDomObj.unmount();
-              $(div).html(
-                '<div class="pg-panel-message" role="alert">' + gettext('Please connect to the selected server to view the dashboard.') + '</div>'
-              );
-              $(dashboardPanel).data('server_status', false);
-            }
-            // Cache the current IDs for next time
-            $(dashboardPanel).data('dashboard_url', url);
-          }
-        }
-      }
-    },
-
-    // Handler function to support the "Add Server" link
-    add_new_server: function() {
-      if (pgBrowser && pgBrowser.tree) {
-        var i = _.isUndefined(pgBrowser.tree.selected()) ?
-            pgBrowser.tree.first(null, false):
-            pgBrowser.tree.selected(),
-          serverModule = require('pgadmin.node.server'),
-          itemData = pgBrowser.tree.itemData(i);
-
-        while (itemData && itemData._type != 'server_group') {
-          i = pgBrowser.tree.next(i);
-          itemData = pgBrowser.tree.itemData(i);
-        }
-
-        if (!itemData) {
-          return;
-        }
-
-        if (serverModule) {
-          serverModule.callbacks.show_obj_properties.apply(
-            serverModule, [{
-              action: 'create',
-            }, i]
-          );
-        }
-      }
-    },
-
-    // Render a grid
-    render_grid: function(container, url, columns) {
-      var Datum = Backbone.Model.extend({}),
-        self = this;
-
-      var path = url + self.sid;
-      if (self.did != -1) {
-        path += '/' + self.did;
-      }
-
-      var Data = Backbone.Collection.extend({
-        model: Datum,
-        url: path,
-        mode: 'client',
-      });
-
-      var data = new Data();
-
-      var HighlightedRow = Backgrid.Row.extend({
-        render: function() {
-          Backgrid.Row.prototype.render.call(this);
-          var row_type = this.model.get('row_type');
-
-          if (_.isUndefined(row_type) || _.isNull(row_type)) {
-            this.$el.removeClass('alert');
-            this.$el.removeClass('warning');
-          } else if (row_type === 'warning') {
-            this.$el.addClass('warning');
-          } else if (row_type === 'alert') {
-            this.$el.addClass('alert');
-          }
-
-          return this;
-        }
-      });
-
-      // Set up the grid
-      var grid = new Backgrid.Grid({
-        emptyText: gettext('No data found'),
-        columns: columns,
-        collection: data,
-        className: 'backgrid presentation table table-bordered table-noouter-border table-hover',
-        row: HighlightedRow
-      });
-
-      // Render the grid
-      $(container).empty();
-      $(container).append(grid.render().el);
-
-      // Initialize a client-side filter to filter on the client
-      // mode pageable collection's cache.
-      var filter = new Backgrid.Extension.ClientSideFilter({
-        collection: data,
-      });
-
-      filter.setCustomSearchBox($('#txtGridSearch'));
-      // Stash objects for future use
-      $(container).data('data', data);
-      $(container).data('grid', grid);
-      $(container).data('filter', filter);
-    },
-    __loadMoreRows: function(e) {
-      let elem = e.currentTarget;
-      if ((elem.scrollHeight - 10) < elem.scrollTop + elem.offsetHeight) {
-        if (this.data.length > 0) {
-          this.local_grid.collection.add(this.data.splice(0, 50));
-        }
-      }
-    },
-    // Render the data in a grid
-    render_grid_data: function(container) {
-      var that = this;
-      var data = $(container).data('data'),
-        grid = $(container).data('grid'),
-        filter = $(container).data('filter');
-
-      if (_.isUndefined(data)) {
-        return null;
-      }
-
-      data.fetch({
-        reset: true,
-        success: function(res) {
-          that.data = res.models;
-          that.local_grid = grid;
-          grid.collection.reset(that.data.splice(0,50));
-
-          // If we're showing an error, remove it, and replace the grid & filter
-          if ($(container).hasClass('grid-error')) {
-            $(container).removeClass('grid-error');
-            $(container).html(grid.render().el);
-            $(filter.el).show();
-          }
-
-          if(that.data.length > 50) {
-            // Listen scroll event to load more rows
-            $('.wcScrollableY').on('scroll', that.__loadMoreRows.bind(that));
-          } else {
-            // Listen scroll event to load more rows
-            $('.wcScrollableY').off('scroll', that.__loadMoreRows);
-          }
-
-          // Re-apply search criteria
-          filter.search();
-        },
-        error: function(model, xhr) {
-          let err = '';
-          let msg = '';
-          let cls = 'info';
-
-          if (xhr.readyState === 0) {
-            msg = gettext('Not connected to the server or the connection to the server has been closed.');
-          } else {
-            err = JSON.parse(xhr.responseText);
-            msg = err.errormsg;
-
-            // If we get a 428, it means the server isn't connected
-            if (xhr.status === 428) {
-              if (_.isUndefined(msg) || _.isNull(msg)) {
-                msg = gettext('Please connect to the selected server to view the table.');
-              }
-            } else {
-              msg = gettext('An error occurred whilst rendering the table.');
-              cls = 'error';
-            }
-          }
-
-          // Replace the content with the error, if not already present. Always update the message
-          if (!$(container).hasClass('grid-error')) {
-            $(filter.el).hide();
-            $(container).addClass('grid-error');
-          }
-
-          $(container).html(
-            '<div class="pg-panel-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
-          );
-
-          // Try again
-          setTimeout(function() {
-            pgAdmin.Dashboard.render_grid_data(container, data);
-          }, 5000);
-        },
-      });
-    },
-
-    // Rock n' roll on the dashboard
-    init_dashboard: function() {
-      let self = this;
-
-      this.chartsDomObj = new ChartsDOM.default(
-        document.getElementById('dashboard-graphs'),
-        self.preferences,
-        self.sid,
-        self.did,
-        $('.dashboard-container')[0].clientHeight <=0 ? false : true
-      );
-
-      /* Cache may take time to load for the first time
-       * Keep trying till available
-       */
-      let cacheIntervalId = setInterval(function() {
-        try {
-          if(pgWindow.default.pgAdmin.Browser.preference_version() > 0) {
-            clearInterval(cacheIntervalId);
-            self.reflectPreferences();
-          }
-        }
-        catch(err) {
-          clearInterval(cacheIntervalId);
-          throw err;
-        }
-      },0);
-
-      /* Register for preference changed event broadcasted */
-      pgBrowser.onPreferencesChange('dashboards', function() {
-        self.reflectPreferences();
-      });
-    },
-
-    reflectPreferences: function() {
-      var self = this;
-      self.preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('dashboards');
-      this.chartsDomObj.reflectPreferences(self.preferences);
-
-      if(is_server_dashboard || is_database_dashboard) {
-        if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
-          $('#dashboard-activity').removeClass('dashboard-hidden');
-        }
-        else if(!self.preferences.show_activity) {
-          $('#dashboard-activity').addClass('dashboard-hidden');
-        }
-
-        if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
-          $('#dashboard-activity').removeClass('dashboard-hidden');
-        }
-        else if(!self.preferences.show_activity) {
-          $('#dashboard-activity').addClass('dashboard-hidden');
-        }
-
-        /* Dashboard specific preferences can be updated in the
-         * appropriate functions
-         */
-        if(is_server_dashboard) {
-          self.reflectPreferencesServer();
-        }
-        else if(is_database_dashboard) {
-          self.reflectPreferencesDatabase();
-        }
-      }
-    },
-
-    renderTab: function(e, tab_grid_map) {
-      let prevGrid = tab_grid_map[$(e.relatedTarget).attr('aria-controls')];
-      $(prevGrid).data('filtertext', $('#txtGridSearch').val());
-
-      let currGrid = tab_grid_map[$(e.target).attr('aria-controls')];
-      $('#txtGridSearch').val($(currGrid).data('filtertext'));
-      pgAdmin.Dashboard.render_grid_data(currGrid);
-    },
-
-    reflectPreferencesServer: function() {
-      var self = this;
-      var $dashboardContainer = $('.dashboard-container');
-      var div_server_activity = $dashboardContainer.find('#server_activity').get(0);
-      var div_server_locks = $dashboardContainer.find('#server_locks').get(0);
-      var div_server_prepared = $dashboardContainer.find('#server_prepared').get(0);
-      var div_server_config = $dashboardContainer.find('#server_config').get(0);
-
-      var tab_grid_map = {
-        'tab_server_activity': div_server_activity,
-        'tab_server_locks': div_server_locks,
-        'tab_server_prepared': div_server_prepared,
-        'tab_server_config': div_server_config,
-      };
-
-      // Display server activity
-      if (self.preferences.show_activity) {
-        var server_activity_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'datname',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'usename',
-          label: gettext('User'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'application_name',
-          label: gettext('Application'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'client_addr',
-          label: gettext('Client'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'backend_start',
-          label: gettext('Backend start'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'state',
-          label: gettext('State'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        if (self.version < 90600) {
-          server_activity_columns = server_activity_columns.concat(
-            [{
-              name: 'waiting',
-              label: gettext('Waiting?'),
-              editable: false,
-              cell: 'string',
-            }]);
-        } else {
-          server_activity_columns = server_activity_columns.concat(
-            [{
-              name: 'wait_event',
-              label: gettext('Wait event'),
-              editable: false,
-              cell: 'string',
-            }, {
-              name: 'blocking_pids',
-              label: gettext('Blocking PIDs'),
-              editable: false,
-              cell: 'string',
-            }]);
-        }
-
-        var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
-
-        var subNodeFieldsModel = Backform.generateViewSchema(
-          null, newActiveQueryDetailsModel, 'create', null, null, true
-        );
-
-        // Add version to each field
-        _.each(subNodeFieldsModel[0].fields, function(obj) {
-          obj['version'] = self.version;
-        });
-
-        // Add cancel active query button
-        server_activity_columns.unshift({
-          name: 'pg-backform-expand',
-          label: '',
-          cell: SessionDetailsCell,
-          cell_priority: -1,
-          postgres_version: self.version,
-          schema: subNodeFieldsModel,
-        });
-
-        // Add cancel active query button
-        server_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'cancel',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        server_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'terminate',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        var server_locks_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'datname',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'locktype',
-          label: gettext('Lock type'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'relation',
-          label: gettext('Target relation'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'page',
-          label: gettext('Page'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'tuple',
-          label: gettext('Tuple'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualxid',
-          label: gettext('vXID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transactionid',
-          label: gettext('XID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'classid',
-          label: gettext('Class'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'objid',
-          label: gettext('Object ID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualtransaction',
-          label: gettext('vXID (owner)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'mode',
-          label: gettext('Mode'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'granted',
-          label: gettext('Granted?'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var server_prepared_columns = [{
-          name: 'git',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'database',
-          label: gettext('Database'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'Owner',
-          label: gettext('Owner'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transaction',
-          label: gettext('XID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'prepared',
-          label: gettext('Prepared at'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var server_config_columns = [{
-          name: 'name',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'category',
-          label: gettext('Category'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'setting',
-          label: gettext('Setting'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'unit',
-          label: gettext('Unit'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'short_desc',
-          label: gettext('Description'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        // To align subnode controls properly
-        $(div_server_activity).addClass('pg-el-container');
-        $(div_server_activity).attr('el', 'sm');
-
-        // Render the tabs, but only get data for the activity tab for now
-        pgAdmin.Dashboard.render_grid(
-          div_server_activity, url_for('dashboard.activity'), server_activity_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_locks, url_for('dashboard.locks'), server_locks_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_prepared, url_for('dashboard.prepared'), server_prepared_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_server_config, url_for('dashboard.config'), server_config_columns
-        );
-
-        pgAdmin.Dashboard.render_grid_data(div_server_activity);
-
-        // (Re)render the appropriate tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
-          self.renderTab(e, tab_grid_map);
-        });
-
-        $('#btn_refresh').off('click').on('click', () => {
-          let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
-          pgAdmin.Dashboard.render_grid_data(currGrid);
-        });
-      }
-    },
-    reflectPreferencesDatabase: function() {
-      var self = this;
-      var div_database_activity = document.getElementById('database_activity');
-      var div_database_locks = document.getElementById('database_locks');
-      var div_database_prepared = document.getElementById('database_prepared');
-
-      var tab_grid_map = {
-        'tab_database_activity': div_database_activity,
-        'tab_database_locks': div_database_locks,
-        'tab_database_prepared': div_database_prepared,
-      };
-
-      // Display server activity
-      if (self.preferences.show_activity) {
-        var database_activity_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'usename',
-          label: gettext('User'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'application_name',
-          label: gettext('Application'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'client_addr',
-          label: gettext('Client'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'backend_start',
-          label: gettext('Backend start'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'state',
-          label: gettext('State'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        if (self.version < 90600) {
-          database_activity_columns = database_activity_columns.concat(
-            [{
-              name: 'waiting',
-              label: gettext('Waiting?'),
-              editable: false,
-              cell: 'string',
-            }]);
-        } else {
-          database_activity_columns = database_activity_columns.concat(
-            [{
-              name: 'wait_event',
-              label: gettext('Wait event'),
-              editable: false,
-              cell: 'string',
-            }, {
-              name: 'blocking_pids',
-              label: gettext('Blocking PIDs'),
-              editable: false,
-              cell: 'string',
-            }]);
-        }
-
-        var newActiveQueryDetailsModel = new ActiveQueryDetailsModel();
-
-        var subNodeFieldsModel = Backform.generateViewSchema(
-          null, newActiveQueryDetailsModel, 'create', null, null, true
-        );
-
-        // Add version to each field
-        _.each(subNodeFieldsModel[0].fields, function(obj) {
-          obj['version'] = self.version;
-        });
-
-        // Add cancel active query button
-        database_activity_columns.unshift({
-          name: 'pg-backform-expand',
-          label: '',
-          cell: SessionDetailsCell,
-          cell_priority: -1,
-          postgres_version: self.version,
-          schema: subNodeFieldsModel,
-        });
-
-        database_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'cancel',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-        database_activity_columns.unshift({
-          name: 'pg-backform-delete',
-          label: '',
-          cell: customDashboardActionCell,
-          cell_action: 'terminate',
-          editable: false,
-          cell_priority: -1,
-          canDeleteRow: pgAdmin.Dashboard.can_take_action,
-          postgres_version: self.version,
-        });
-
-        var database_locks_columns = [{
-          name: 'pid',
-          label: gettext('PID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'locktype',
-          label: gettext('Lock type'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'relation',
-          label: gettext('Target relation'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'page',
-          label: gettext('Page'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'tuple',
-          label: gettext('Tuple'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualxid',
-          label: gettext('vXID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transactionid',
-          label: gettext('XID (target)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'classid',
-          label: gettext('Class'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'objid',
-          label: gettext('Object ID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'virtualtransaction',
-          label: gettext('vXID (owner)'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'mode',
-          label: gettext('Mode'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'granted',
-          label: gettext('Granted?'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        var database_prepared_columns = [{
-          name: 'git',
-          label: gettext('Name'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'Owner',
-          label: gettext('Owner'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'transaction',
-          label: gettext('XID'),
-          editable: false,
-          cell: 'string',
-        }, {
-          name: 'prepared',
-          label: gettext('Prepared at'),
-          editable: false,
-          cell: 'string',
-        }];
-
-        // To align subnode controls properly
-        $(div_database_activity).addClass('pg-el-container');
-        $(div_database_activity).attr('el', 'sm');
-
-        // Render the tabs, but only get data for the activity tab for now
-        pgAdmin.Dashboard.render_grid(
-          div_database_activity, url_for('dashboard.activity'), database_activity_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_database_locks, url_for('dashboard.locks'), database_locks_columns
-        );
-        pgAdmin.Dashboard.render_grid(
-          div_database_prepared, url_for('dashboard.prepared'), database_prepared_columns
-        );
-
-        pgAdmin.Dashboard.render_grid_data(div_database_activity);
-
-        // (Re)render the appropriate tab
-        $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
-          self.renderTab(e, tab_grid_map);
-        });
-
-        $('#btn_refresh').off('click').on('click', () => {
-          let currGrid = tab_grid_map[$('#dashboard-activity .nav-tabs .active').attr('aria-controls')];
-          pgAdmin.Dashboard.render_grid_data(currGrid);
-        });
-      }
-    },
-    toggleVisibility: function(visible, closed=false) {
-      dashboardVisible = visible;
-      if(closed) {
-        this.chartsDomObj && this.chartsDomObj.unmount();
-      } else {
-        var t = pgBrowser.tree,
-          i = t ? t.selected() : 0,
-          d = i && t.itemData(i);
-
-        this.chartsDomObj && this.chartsDomObj.setPageVisible(dashboardVisible);
-        this.object_selected(i, d);
-      }
-    },
-    can_take_action: function(m) {
-      // We will validate if user is allowed to cancel the active query
-      // If there is only one active session means it probably our main
-      // connection session
-      var active_sessions = m.collection.where({
-          'state': 'active',
-        }),
-        pg_version = this.get('postgres_version') || null,
-        cell_action = this.get('cell_action') || null,
-        is_cancel_session = cell_action === 'cancel',
-        txtMessage;
-
-      // With PG10, We have background process showing on dashboard
-      // We will not allow user to cancel them as they will fail with error
-      // anyway, so better usability we will throw our on notification
-
-      // Background processes do not have database field populated
-      if (pg_version && pg_version >= 100000 && !m.get('datname')) {
-        if (is_cancel_session) {
-          txtMessage = gettext('You cannot cancel background worker processes.');
-        } else {
-          txtMessage = gettext('You cannot terminate background worker processes.');
-        }
-        Notify.info(txtMessage);
-        return false;
-        // If it is the last active connection on maintenance db then error out
-      } else if (maintenance_database == m.get('datname') &&
-        m.get('state') == 'active' && active_sessions.length == 1) {
-        if (is_cancel_session) {
-          txtMessage = gettext('You are not allowed to cancel the main active session.');
-        } else {
-          txtMessage = gettext('You are not allowed to terminate the main active session.');
-        }
-        Notify.error(txtMessage);
-        return false;
-      } else if (is_cancel_session && m.get('state') == 'idle') {
-        // If this session is already idle then do nothing
-        Notify.info(
-          gettext('The session is already in idle state.')
-        );
-        return false;
-      } else if (can_signal_backend) {
-        // user with membership of 'pg_signal_backend' can terminate the session of non admin user.
-        return true;
-      } else if (is_super_user) {
-        // Super user can do anything
-        return true;
-      } else if (current_user && current_user == m.get('usename')) {
-        // Non-super user can cancel only their active queries
-        return true;
-      } else {
-        // Do not allow to cancel someone else session to non-super user
-        if (is_cancel_session) {
-          txtMessage = gettext('Superuser privileges are required to cancel another users query.');
-        } else {
-          txtMessage = gettext('Superuser privileges are required to terminate another users query.');
-        }
-        Notify.error(txtMessage);
-        return false;
-      }
-    },
-  };
-
-  return pgAdmin.Dashboard;
-});
diff --git a/web/pgadmin/dashboard/static/js/dashboard_components.jsx b/web/pgadmin/dashboard/static/js/dashboard_components.jsx
deleted file mode 100644
index a723dd242..000000000
--- a/web/pgadmin/dashboard/static/js/dashboard_components.jsx
+++ /dev/null
@@ -1,74 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export function ChartContainer(props) {
-  return (
-    <div className="card dashboard-graph" role="object-document" tabIndex="0" aria-labelledby={props.id}>
-      <div className="card-header">
-        <div className="d-flex">
-          <div id={props.id}>{props.title}</div>
-          <div className="ml-auto my-auto legend" ref={props.legendRef}></div>
-        </div>
-      </div>
-      <div className="card-body dashboard-graph-body">
-        <div className={'chart-wrapper ' + (props.errorMsg ? 'd-none': '')}>
-          {props.children}
-        </div>
-        <ChartError message={props.errorMsg} />
-      </div>
-    </div>
-  );
-}
-
-ChartContainer.propTypes = {
-  id: PropTypes.string.isRequired,
-  title: PropTypes.string.isRequired,
-  legendRef: PropTypes.oneOfType([
-    PropTypes.func,
-    PropTypes.shape({ current: PropTypes.any }),
-  ]).isRequired,
-  children: PropTypes.node.isRequired,
-  errorMsg: PropTypes.string,
-};
-
-export function ChartError(props) {
-  if(props.message === null) {
-    return  <></>;
-  }
-  return (
-    <div className="pg-panel-error pg-panel-message" role="alert">{props.message}</div>
-  );
-}
-
-ChartError.propTypes = {
-  message: PropTypes.string,
-};
-
-export function DashboardRow({children}) {
-  return (
-    <div className="row dashboard-row">{children}</div>
-  );
-}
-DashboardRow.propTypes = {
-  children: PropTypes.node.isRequired,
-};
-
-export function DashboardRowCol({breakpoint, parts, children}) {
-  return (
-    <div className={`col-${breakpoint}-${parts}`}>{children}</div>
-  );
-}
-
-DashboardRowCol.propTypes = {
-  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
-  parts: PropTypes.number.isRequired,
-  children: PropTypes.node.isRequired,
-};
diff --git a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html
deleted file mode 100644
index 148ce96ab..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/database_dashboard.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<div class="container-fluid dashboard-container negative-space">
-    <div id="dashboard-graphs"></div>
-    <div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
-        <div class="card-header">
-            <span id="dashboard-activity-header">{{ _('Server activity') }}</span>
-        </div>
-        <div class="card-body">
-            <div class="row">
-                <div class="col-md-9 col-12 pr-0">
-                    <ul class="nav nav-tabs" role="tablist" aria-labelledby="dashboard-activity-header">
-                        <li class="nav-item">
-                            <a class="nav-link active show" id="tab_panel_database_activity_tab" href="#tab_panel_database_activity" aria-controls="tab_database_activity"
-                                role="tab" data-toggle="tab">{{ _('Sessions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_database_locks_tab" href="#tab_panel_database_locks" aria-controls="tab_database_locks"
-                               role="tab" data-toggle="tab">{{ _('Locks') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_database_prepared_tab" href="#tab_panel_database_prepared" aria-controls="tab_database_prepared"
-                               role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
-                        </li>
-                    </ul>
-                </div>
-                <div class="col-md-3 col-12 pl-0 text-right">
-                    <div class="navtab-inline-controls">
-                        <div class="input-group">
-                            <div class="input-group-prepend">
-                                <span class="input-group-text fa fa-search" id="labelSearch" aria-label="{{ _('Search') }}"></span>
-                            </div>
-                            <input type="search" class="form-control" id="txtGridSearch" placeholder="{{ _('Search') }}" aria-describedby="labelSearch" aria-labelledby="labelSearch">
-                        </div>
-                        <button id="btn_refresh" type="button" class="btn btn-primary-icon btn-navtab-inline" title="{{ _('Refresh') }}" aria-label="{{ _('Refresh') }}">
-                            <span class="fa fa-sync-alt" aria-hidden="true"></span>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <!-- Nav tabs -->
-
-
-            <!-- Tab panes -->
-            <div class="tab-content">
-                <div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_database_activity" aria-labelledby="tab_panel_database_activity_tab">
-                    <div id="database_activity" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_locks" aria-labelledby="tab_panel_database_locks_tab">
-                    <div id="database_locks" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_database_prepared" aria-labelledby="tab_panel_database_prepared_tab">
-                    <div id="database_prepared" class="grid-container"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
-        {{ _('All Dashboard elements are currently disabled.') }}
-    </div>
-</div>
diff --git a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html
deleted file mode 100644
index 874a1e206..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/server_dashboard.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<div class="container-fluid dashboard-container negative-space">
-    <div id="dashboard-graphs">
-    </div>
-    <div id="dashboard-activity" class="card dashboard-row dashboard-hidden">
-        <div class="card-header">
-            <span id="server-activity-header">{{ _('Server activity') }}</span>
-        </div>
-        <div class="card-body">
-            <div class="row">
-                <div class="col-md-9 col-12 pr-0">
-                    <ul class="nav nav-tabs" role="tablist" aria-labelledby="server-activity-header">
-                        <li class="nav-item">
-                            <a class="nav-link active show" id="tab_panel_server_activity_tab" href="#tab_panel_server_activity" aria-controls="tab_server_activity"
-                                role="tab" data-toggle="tab">{{_('Sessions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_locks_tab" href="#tab_panel_server_locks" aria-controls="tab_server_locks"
-                                role="tab" data-toggle="tab">{{ _('Locks') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_prepared_tab" href="#tab_panel_server_prepared" aria-controls="tab_server_prepared"
-                                role="tab" data-toggle="tab">{{ _('Prepared Transactions') }}</a>
-                        </li>
-                        <li class="nav-item">
-                            <a class="nav-link" id="tab_panel_server_config_tab" href="#tab_panel_server_config" aria-controls="tab_server_config"
-                                role="tab" data-toggle="tab">{{ _('Configuration') }}</a>
-                        </li>
-                    </ul>
-                </div>
-                <div class="col-md-3 col-12 pl-0 text-right">
-                    <div class="navtab-inline-controls">
-                        <div class="input-group">
-                            <div class="input-group-prepend">
-                                <span class="input-group-text fa fa-search" id="labelSearch"></span>
-                            </div>
-                            <input type="search" class="form-control" id="txtGridSearch" placeholder="{{ _('Search') }}" aria-label="{{ _('Search') }}" aria-describedby="labelSearch">
-                        </div>
-                        <button id="btn_refresh" type="button" class="btn btn-primary-icon btn-navtab-inline" title="{{ _('Refresh') }}" aria-label="{{ _('Refresh') }}">
-                            <span class="fa fa-sync-alt" aria-hidden="true"></span>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <!-- Nav tabs -->
-
-
-            <!-- Tab panes -->
-            <div class="tab-content">
-                <div role="tabpanel" class="tab-pane negative-space p-2 active show" id="tab_panel_server_activity" aria-labelledby="tab_panel_server_activity_tab">
-                    <div id="server_activity" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_locks" aria-labelledby="tab_panel_server_locks_tab">
-                    <div id="server_locks" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_prepared" aria-labelledby="tab_panel_server_prepared_tab">
-                    <div id="server_prepared" class="grid-container"></div>
-                </div>
-                <div role="tabpanel" class="tab-pane negative-space p-2" id="tab_panel_server_config" aria-labelledby="tab_panel_server_config_tab">
-                    <div id="server_config" class="grid-container"></div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div id="dashboard-none-show" class="alert alert-info pg-panel-message dashboard-hidden" role="alert">
-        {{ _('All Dashboard elements are currently disabled.') }}
-    </div>
-</div>
diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql b/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql
index a9379f67b..d02d071fc 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/10_plus/activity.sql
@@ -12,6 +12,7 @@ SELECT
     query,
     pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
     pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
+    pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
     backend_type,
     CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
 FROM
diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql b/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql
index b0a9c5847..67cb4588f 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/9.6_plus/activity.sql
@@ -11,6 +11,7 @@ SELECT
     pg_catalog.pg_blocking_pids(pid) AS blocking_pids,
     query,
     pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
+    pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
     pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
     CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
 FROM
diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql b/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql
index 494b5adbb..3e6cf81b0 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/default/activity.sql
@@ -10,6 +10,7 @@ SELECT
     CASE WHEN waiting THEN '{{ _('yes') }}' ELSE '{{ _('no') }}' END AS waiting,
     query,
     pg_catalog.to_char(state_change, 'YYYY-MM-DD HH24:MI:SS TZ') AS state_change,
+    pg_catalog.to_char(xact_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS xact_start,
     pg_catalog.to_char(query_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS query_start,
     CASE WHEN state = 'active' THEN ROUND((extract(epoch from now() - query_start) / 60)::numeric, 2) ELSE 0 END AS active_since
 FROM
diff --git a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html b/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html
deleted file mode 100644
index fc798ab19..000000000
--- a/web/pgadmin/dashboard/templates/dashboard/welcome_dashboard.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<div class="container-fluid negative-space">
-    <div class="dashboard-container">
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card">
-                    <div class="card-header">{{ _('Welcome') }}</div>
-                    <div class="card-body p-2">
-                        <div class="welcome-logo" aria-hidden="true">
-                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 130">
-                               <defs>
-                                  <style>.cls-1{stroke:#000;stroke-width:10.19px;}.cls-2{fill:#336791;}.cls-3,.cls-4,.cls-9{fill:none;}.cls-3,.cls-4,.cls-5,.cls-6{stroke:#fff;}.cls-3,.cls-4{stroke-linecap:round;stroke-width:3.4px;}.cls-3{stroke-linejoin:round;}.cls-4{stroke-linejoin:bevel;}.cls-5,.cls-6{fill:#fff;}.cls-5{stroke-width:1.13px;}.cls-6{stroke-width:0.57px;}.cls-7{fill:#2775b6;}.cls-8{fill:#333;}.cls-9{stroke:#333;stroke-width:3px;}</style>
-                               </defs>
-                               <title>pgAdmin_PostgreSQL</title>
-                               <g id="Layer_1" data-name="Layer 1">
-                                  <g id="Layer_3">
-                                     <path class="cls-1" d="M95.59,93.65c.77-6.44.54-7.38,5.33-6.34l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21a9,9,0,0,0,.1,2.46c-3.7,4.13-2.62,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.46,1.16,1.36,8.35,1.56,13.48s.55,9.93,1.6,12.75,2.28,10.1,12,8C88.81,119.46,95,117,95.59,93.65" />
-                                     <path class="cls-2" d="M117.17,79.2c-13.71,2.83-14.65-1.81-14.65-1.81C117,55.91,123,28.64,117.82,22,103.57,3.76,78.91,12.37,78.5,12.6l-.13,0a48.65,48.65,0,0,0-9.15-.95C63,11.57,58.31,13.29,54.74,16c0,0-44-18.12-41.95,22.8.44,8.7,12.48,65.86,26.84,48.6C44.88,81.08,50,75.75,50,75.75A13.39,13.39,0,0,0,58.65,78l.25-.21A9.41,9.41,0,0,0,59,80.22c-3.7,4.13-2.61,4.86-10,6.38s-3.08,4.29-.21,5c3.48.87,11.53,2.1,17-5.52l-.22.87c1.45,1.16,2.47,7.56,2.3,13.35s-.28,9.77.86,12.88,2.28,10.1,12,8C88.81,119.46,93,115,93.6,107.42,94,102.07,95,102.87,95,98.08l.75-2.26c.87-7.26.14-9.6,5.15-8.51l1.21.11a27.6,27.6,0,0,0,11.34-1.91c6.09-2.83,9.71-7.55,3.7-6.31Z" />
-                                     <path class="cls-3" d="M66.33,83.36c-.38,13.5.09,27.09,1.41,30.39s4.15,9.73,13.88,7.64c8.12-1.74,11.08-5.11,12.36-12.55.94-5.47,2.77-20.67,3-23.79" />
-                                     <path class="cls-3" d="M54.67,15.7s-44-18-42,22.93c.44,8.7,12.48,65.87,26.84,48.6,5.25-6.32,10-11.27,10-11.27" />
-                                     <path class="cls-3" d="M78.45,12.42c-1.52.47,24.49-9.51,39.28,9.38,5.22,6.67-.83,33.94-15.31,55.42" />
-                                     <path class="cls-4" d="M102.42,77.22s.94,4.64,14.65,1.81c6-1.24,2.4,3.48-3.7,6.31-5,2.32-16.21,2.92-16.39-.29-.47-8.27,5.9-5.76,5.44-7.83-.42-1.87-3.26-3.7-5.15-8.27-1.64-4-22.57-34.58,5.8-30,1-.22-7.4-27-33.95-27.42S43.45,44.14,43.45,44.14" />
-                                     <path class="cls-3" d="M58.9,80.05c-3.7,4.13-2.61,4.86-10,6.38s-3.09,4.29-.22,5c3.48.87,11.53,2.1,17-5.52,1.66-2.32,0-6-2.28-7-1.1-.46-2.57-1-4.46,1.09Z" />
-                                     <path class="cls-3" d="M58.66,80c-.38-2.44.79-5.33,2.05-8.71C62.6,66.19,67,61.11,63.47,45c-2.6-12-20-2.5-20-.87a81.48,81.48,0,0,1-.29,16c-1.41,10.06,6.4,18.57,15.39,17.7" />
-                                     <path class="cls-5" d="M54.51,43.9c-.08.55,1,2,2.45,2.23a2.62,2.62,0,0,0,2.72-1.51c.08-.56-1-1.17-2.44-1.37s-2.65.09-2.73.65Z" />
-                                     <path class="cls-6" d="M98,42.76c.07.56-1,2-2.45,2.24a2.64,2.64,0,0,1-2.73-1.52c-.07-.55,1-1.16,2.45-1.36s2.65.09,2.73.64Z" />
-                                     <path class="cls-3" d="M103.07,38.92c.24,4.36-.94,7.33-1.08,12-.22,6.74,3.21,14.46-2,22.19" />
-                                  </g>
-                                  <path class="cls-7 app-name" d="M154.72,28.15h5.16v4.16A12.84,12.84,0,0,1,163.35,29a11.17,11.17,0,0,1,6.28-1.76,11.84,11.84,0,0,1,9.08,4.09c2.48,2.72,3.73,6.62,3.73,11.67q0,10.26-5.38,14.65a12.2,12.2,0,0,1-7.95,2.79,10.78,10.78,0,0,1-6-1.56,13.55,13.55,0,0,1-3.14-3v16h-5.28Zm19.84,24.6Q177,49.65,177,43.5a17,17,0,0,0-1.09-6.44,7.51,7.51,0,0,0-7.53-5.19q-5.49,0-7.52,5.48a21.49,21.49,0,0,0-1.09,7.44A15.64,15.64,0,0,0,160.88,51a8,8,0,0,0,13.68,1.78Z" />
-                                  <path class="cls-7 app-name" d="M206,29.26a14.6,14.6,0,0,1,3,3V28.3h4.86V56.83c0,4-.58,7.13-1.75,9.44q-3.27,6.38-12.35,6.38a15.07,15.07,0,0,1-8.5-2.27,8.86,8.86,0,0,1-3.85-7.1h5.36a6,6,0,0,0,1.52,3.25q1.77,1.75,5.59,1.76,6,0,7.9-4.28,1.1-2.52,1-9a10.39,10.39,0,0,1-3.8,3.57,13.56,13.56,0,0,1-14.75-2.45q-3.81-3.62-3.81-12,0-7.89,3.84-12.31a11.85,11.85,0,0,1,9.27-4.42A11.37,11.37,0,0,1,206,29.26Zm.64,5.66a7.61,7.61,0,0,0-6.09-2.81A7.52,7.52,0,0,0,193,37.32a20.56,20.56,0,0,0-1.08,7.3c0,3.53.72,6.22,2.14,8.07a6.93,6.93,0,0,0,5.76,2.77,8.09,8.09,0,0,0,8-5.13A16.72,16.72,0,0,0,209,43.56Q209,37.73,206.62,34.92Z" />
-                                  <path class="cls-7 app-name" d="M235.16,16.34h6.58l15.62,43H251l-4.5-12.89H229.6l-4.67,12.89h-6Zm9.67,25.4-6.63-19-6.88,19Z" />
-                                  <path class="cls-7 app-name" d="M279.16,29a14.3,14.3,0,0,1,3.18,3.08V16.2h5.07V59.38h-4.75V55a11.33,11.33,0,0,1-4.35,4.19,12.51,12.51,0,0,1-5.75,1.28,11.61,11.61,0,0,1-9-4.4q-3.82-4.41-3.83-11.74a20.35,20.35,0,0,1,3.49-11.88,11.41,11.41,0,0,1,10-5A11.15,11.15,0,0,1,279.16,29ZM267.39,52.5q2.13,3.39,6.82,3.39a7.17,7.17,0,0,0,6-3.14c1.56-2.1,2.35-5.12,2.35-9s-.81-6.9-2.42-8.81a7.56,7.56,0,0,0-6-2.85,7.88,7.88,0,0,0-6.43,3c-1.64,2-2.46,5-2.46,9A15.62,15.62,0,0,0,267.39,52.5Z" />
-                                  <path class="cls-7 app-name" d="M295.29,28h5.21v4.46a17.4,17.4,0,0,1,3.4-3.37,10.24,10.24,0,0,1,5.92-1.79,9.34,9.34,0,0,1,6,1.85,9.61,9.61,0,0,1,2.34,3.1,11.37,11.37,0,0,1,4.13-3.73,11.52,11.52,0,0,1,5.33-1.22q6.33,0,8.62,4.57a15,15,0,0,1,1.23,6.62V59.38H332V37.58c0-2.09-.52-3.52-1.57-4.3a6.2,6.2,0,0,0-3.82-1.17,7.58,7.58,0,0,0-5.35,2.08c-1.49,1.38-2.24,3.7-2.24,6.94V59.38h-5.36V38.9a10.78,10.78,0,0,0-.76-4.66q-1.2-2.19-4.49-2.19A7.73,7.73,0,0,0,303,34.36c-1.63,1.54-2.45,4.34-2.45,8.38V59.38h-5.27Z" />
-                                  <path class="cls-7 app-name" d="M345.27,16.34h5.36v6h-5.36Zm0,11.81h5.36V59.38h-5.36Z" />
-                                  <path class="cls-7 app-name" d="M358.6,28h5v4.46a14,14,0,0,1,4.72-4,12.56,12.56,0,0,1,5.53-1.2c4.46,0,7.46,1.55,9,4.66a16.52,16.52,0,0,1,1.29,7.29V59.38h-5.37V39.61A10.8,10.8,0,0,0,378,35a5.15,5.15,0,0,0-5.1-2.93,10.21,10.21,0,0,0-3.08.38A8,8,0,0,0,366,35a7.66,7.66,0,0,0-1.71,3.2,21.84,21.84,0,0,0-.4,4.74V59.38H358.6Z" />
-                                  <path class="cls-8 app-tagline" d="M155.24,86.87h3.9l5.77,17,5.74-17h3.87V107h-2.6V95.1q0-.61,0-2c0-.94,0-2,0-3L166.24,107h-2.7L157.75,90v.61c0,.49,0,1.24,0,2.25s.05,1.75.05,2.22V107h-2.6Z" />
-                                  <path class="cls-8 app-tagline" d="M186.15,98.09a1.35,1.35,0,0,0,1.14-.71,2.31,2.31,0,0,0,.16-.94,2,2,0,0,0-.89-1.84A4.79,4.79,0,0,0,184,94a3.21,3.21,0,0,0-2.73,1,3.44,3.44,0,0,0-.59,1.72h-2.3A4.28,4.28,0,0,1,180.14,93,7.16,7.16,0,0,1,184.05,92a8,8,0,0,1,4.19,1,3.34,3.34,0,0,1,1.6,3.06v8.44a1.06,1.06,0,0,0,.16.62.77.77,0,0,0,.66.23l.37,0,.44-.07V107a7.38,7.38,0,0,1-.88.21,5.92,5.92,0,0,1-.82,0,2,2,0,0,1-1.84-.9,3.63,3.63,0,0,1-.43-1.36,6.16,6.16,0,0,1-2.16,1.71,6.56,6.56,0,0,1-3.1.73,4.59,4.59,0,0,1-3.33-1.24,4.09,4.09,0,0,1-1.29-3.09,4,4,0,0,1,1.27-3.16,6.16,6.16,0,0,1,3.34-1.38ZM181,104.74a2.88,2.88,0,0,0,1.84.62,5.51,5.51,0,0,0,2.52-.61,3.37,3.37,0,0,0,2-3.26v-2a3.79,3.79,0,0,1-1.16.48,10.37,10.37,0,0,1-1.39.28l-1.49.19a5.68,5.68,0,0,0-2,.56,2.18,2.18,0,0,0-1.14,2A2,2,0,0,0,181,104.74Z" />
-                                  <path class="cls-8 app-tagline" d="M193.88,92.31h2.33v2.08a6.73,6.73,0,0,1,2.2-1.85A6,6,0,0,1,201,92q3.12,0,4.21,2.18a7.73,7.73,0,0,1,.6,3.4V107h-2.5V97.73a4.87,4.87,0,0,0-.4-2.16,2.41,2.41,0,0,0-2.38-1.37,4.75,4.75,0,0,0-1.43.18,3.68,3.68,0,0,0-1.78,1.2,3.55,3.55,0,0,0-.8,1.5,10.3,10.3,0,0,0-.18,2.21V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M217.29,98.09a1.33,1.33,0,0,0,1.14-.71,2.15,2.15,0,0,0,.16-.94,2,2,0,0,0-.89-1.84,4.79,4.79,0,0,0-2.56-.56,3.24,3.24,0,0,0-2.73,1,3.44,3.44,0,0,0-.58,1.72h-2.3A4.27,4.27,0,0,1,211.28,93,7.19,7.19,0,0,1,215.2,92a8,8,0,0,1,4.19,1A3.36,3.36,0,0,1,221,96v8.44a1.14,1.14,0,0,0,.15.62.79.79,0,0,0,.67.23l.37,0,.43-.07V107a7.32,7.32,0,0,1-.87.21,6,6,0,0,1-.82,0,2,2,0,0,1-1.85-.9,3.46,3.46,0,0,1-.42-1.36,6.16,6.16,0,0,1-2.16,1.71,6.63,6.63,0,0,1-3.11.73,4.58,4.58,0,0,1-3.32-1.24,4.06,4.06,0,0,1-1.3-3.09A4,4,0,0,1,210,100a6.13,6.13,0,0,1,3.33-1.38Zm-5.18,6.65a2.91,2.91,0,0,0,1.85.62,5.47,5.47,0,0,0,2.51-.61,3.38,3.38,0,0,0,2.06-3.26v-2a3.9,3.9,0,0,1-1.16.48,10.51,10.51,0,0,1-1.4.28l-1.48.19a5.55,5.55,0,0,0-2,.56,2.17,2.17,0,0,0-1.15,2A2,2,0,0,0,212.11,104.74Z" />
-                                  <path class="cls-8 app-tagline" d="M233.16,92.9a7.05,7.05,0,0,1,1.42,1.39V92.45h2.27v13.32a10,10,0,0,1-.82,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.15,4.15,0,0,1-1.8-3.32H227a2.81,2.81,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.88,0,3.1-.66,3.68-2a11.15,11.15,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,5.93,5.93,0,0,1-2.74.54,5.79,5.79,0,0,1-4.14-1.69q-1.79-1.68-1.78-5.58a8.49,8.49,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.33,5.33,0,0,1,233.16,92.9Zm.3,2.64a3.77,3.77,0,0,0-6.38,1.12,9.73,9.73,0,0,0-.5,3.4,6.05,6.05,0,0,0,1,3.77,3.21,3.21,0,0,0,2.68,1.29,3.77,3.77,0,0,0,3.72-2.39,7.71,7.71,0,0,0,.6-3.16A6.13,6.13,0,0,0,233.46,95.54Z" />
-                                  <path class="cls-8 app-tagline" d="M249.64,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,17.44,17.44,0,0,1,.22,3.23H242.4a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3.05-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.58,6.58,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.71,8.71,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,249.64,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M256.16,92.31h2.44v2.08a8.23,8.23,0,0,1,1.58-1.57A4.79,4.79,0,0,1,263,92a4.31,4.31,0,0,1,2.81.87,4.5,4.5,0,0,1,1.1,1.44,5.27,5.27,0,0,1,1.92-1.74,5.37,5.37,0,0,1,2.49-.57,4.08,4.08,0,0,1,4,2.14,7,7,0,0,1,.58,3.09V107h-2.56V96.78a2.41,2.41,0,0,0-.73-2,2.93,2.93,0,0,0-1.79-.54,3.53,3.53,0,0,0-2.49,1,4.23,4.23,0,0,0-1.05,3.24V107h-2.5V97.4a5,5,0,0,0-.36-2.18,2.17,2.17,0,0,0-2.09-1,3.59,3.59,0,0,0-2.53,1.08c-.76.72-1.14,2-1.14,3.91V107h-2.47Z" />
-                                  <path class="cls-8 app-tagline" d="M288.53,92.72a5.47,5.47,0,0,1,2.22,1.89,6.67,6.67,0,0,1,1,2.58,17.66,17.66,0,0,1,.21,3.23H281.29a6.42,6.42,0,0,0,1,3.59,3.48,3.48,0,0,0,3,1.35,3.9,3.9,0,0,0,3.06-1.28,4.5,4.5,0,0,0,.9-1.72h2.42a5.23,5.23,0,0,1-.64,1.8,6.56,6.56,0,0,1-1.2,1.62,5.7,5.7,0,0,1-2.76,1.48,8.62,8.62,0,0,1-2,.21,6.14,6.14,0,0,1-4.61-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.91-5.72,6.24,6.24,0,0,1,5-2.21A6.58,6.58,0,0,1,288.53,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.53,3.53,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.63,4.63,0,0,0-1.2,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M295.06,92.31h2.34v2.08a6.63,6.63,0,0,1,2.2-1.85,5.91,5.91,0,0,1,2.58-.56c2.08,0,3.49.73,4.21,2.18a7.57,7.57,0,0,1,.61,3.4V107h-2.51V97.73a5,5,0,0,0-.39-2.16,2.41,2.41,0,0,0-2.38-1.37,4.86,4.86,0,0,0-1.44.18,3.7,3.7,0,0,0-1.77,1.2,3.55,3.55,0,0,0-.8,1.5,9.58,9.58,0,0,0-.19,2.21V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M311.13,88.22h2.48v4.09H316v2h-2.34v9.56a1,1,0,0,0,.52,1,2.21,2.21,0,0,0,1,.15h.38l.48,0v2a4.16,4.16,0,0,1-.88.18,7.74,7.74,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88,3.94,3.94,0,0,1-.61-2.29v-9.7h-2v-2h2Z" />
-                                  <path class="cls-8 app-tagline" d="M340.63,86.87v2.39h-6.77V107h-2.75V89.26h-6.76V86.87Z" />
-                                  <path class="cls-8 app-tagline" d="M350.31,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2A8.08,8.08,0,0,1,338.7,100a8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.6,6.6,0,0,1,350.31,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.49,3.49,0,0,0-3.25,1.72,8.07,8.07,0,0,0-1,4.15,7.05,7.05,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.35,3.35,0,0,0,348.78,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M365.88,93.77a7.42,7.42,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.19,6.19,0,0,1-5.31,2.3,6,6,0,0,1-4.76-2,8.08,8.08,0,0,1-1.77-5.48,8.78,8.78,0,0,1,1.86-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,365.88,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.46,3.46,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.54,3.54,0,0,0,3.21,1.56A3.35,3.35,0,0,0,364.35,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M370.91,86.87h2.46V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M378.53,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.86,4.86,0,0,0,2.45-.6A2,2,0,0,0,386,103a1.56,1.56,0,0,0-.84-1.43,10.63,10.63,0,0,0-2.14-.7l-2-.49a10,10,0,0,1-2.81-1,3.11,3.11,0,0,1-1.61-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.83,1.94a4.24,4.24,0,0,1,.91,2.65h-2.33A2.72,2.72,0,0,0,385,95a3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.65,1.65,0,0,0-.74,1.4,1.73,1.73,0,0,0,1,1.53,5.69,5.69,0,0,0,1.64.6l1.66.4A12.73,12.73,0,0,1,387,99.75a3.3,3.3,0,0,1,1.44,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43c-2.2,0-3.77-.5-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z" />
-                                  <path class="cls-8 app-tagline" d="M400,87.84c.58-.84,1.68-1.26,3.32-1.26l.48,0,.56,0v2.24l-.56,0h-.32c-.76,0-1.21.19-1.36.58a11.75,11.75,0,0,0-.22,3h2.46v1.94h-2.46V107h-2.43V94.32h-2V92.38h2v-2.3A4.43,4.43,0,0,1,400,87.84Z" />
-                                  <path class="cls-8 app-tagline" d="M417.23,93.77a7.38,7.38,0,0,1,1.94,5.55,9.57,9.57,0,0,1-1.71,5.85,6.18,6.18,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2,8.07,8.07,0,0,1-1.76-5.48,8.83,8.83,0,0,1,1.85-5.88,6.25,6.25,0,0,1,5-2.18A6.58,6.58,0,0,1,417.23,93.77Zm-1.53,9.74a9.32,9.32,0,0,0,.9-4.12,7.26,7.26,0,0,0-.65-3.33,3.63,3.63,0,0,0-3.54-2,3.47,3.47,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.55,3.55,0,0,0,3.22,1.56A3.35,3.35,0,0,0,415.7,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M422.26,92.31h2.34v2.53A5.61,5.61,0,0,1,426,93,3.68,3.68,0,0,1,428.59,92l.24,0,.56,0v2.6a2.08,2.08,0,0,0-.41-.05l-.4,0a3.52,3.52,0,0,0-2.86,1.2,4.2,4.2,0,0,0-1,2.75V107h-2.46Z" />
-                                  <path class="cls-8 app-tagline" d="M439.89,86.87h9a6.09,6.09,0,0,1,4.31,1.51,5.5,5.5,0,0,1,1.64,4.25,6.15,6.15,0,0,1-1.47,4.09,5.5,5.5,0,0,1-4.47,1.74h-6.27V107h-2.72Zm10.55,2.76a5.92,5.92,0,0,0-2.46-.42h-5.37v7H448a5.07,5.07,0,0,0,2.95-.78,3.1,3.1,0,0,0,1.14-2.75A3,3,0,0,0,450.44,89.63Z" />
-                                  <path class="cls-8 app-tagline" d="M468.58,93.77a7.38,7.38,0,0,1,1.95,5.55,9.51,9.51,0,0,1-1.72,5.85,6.17,6.17,0,0,1-5.3,2.3,6,6,0,0,1-4.77-2A8.07,8.07,0,0,1,457,100a8.78,8.78,0,0,1,1.86-5.88,6.23,6.23,0,0,1,5-2.18A6.56,6.56,0,0,1,468.58,93.77Zm-1.52,9.74a9.32,9.32,0,0,0,.9-4.12,7.39,7.39,0,0,0-.65-3.33,3.65,3.65,0,0,0-3.55-2,3.48,3.48,0,0,0-3.24,1.72,8,8,0,0,0-1,4.15,7,7,0,0,0,1,3.89,3.56,3.56,0,0,0,3.22,1.56A3.36,3.36,0,0,0,467.06,103.51Z" />
-                                  <path class="cls-8 app-tagline" d="M475,102.36a3.47,3.47,0,0,0,.63,1.89,4,4,0,0,0,3.29,1.19,4.93,4.93,0,0,0,2.46-.6,2,2,0,0,0,1.06-1.84,1.55,1.55,0,0,0-.85-1.43,10.4,10.4,0,0,0-2.14-.7l-2-.49a9.78,9.78,0,0,1-2.8-1,3.1,3.1,0,0,1-1.62-2.76,4.21,4.21,0,0,1,1.52-3.37,6.13,6.13,0,0,1,4.08-1.28q3.36,0,4.84,1.94a4.17,4.17,0,0,1,.9,2.65h-2.33a2.72,2.72,0,0,0-.6-1.51,3.92,3.92,0,0,0-3-1,3.7,3.7,0,0,0-2.16.53,1.64,1.64,0,0,0-.73,1.4,1.72,1.72,0,0,0,1,1.53,5.66,5.66,0,0,0,1.65.6l1.65.4a12.83,12.83,0,0,1,3.63,1.24,3.31,3.31,0,0,1,1.43,3,4.48,4.48,0,0,1-1.5,3.37,6.45,6.45,0,0,1-4.58,1.43q-3.3,0-4.68-1.49a5.59,5.59,0,0,1-1.48-3.67Z" />
-                                  <path class="cls-8 app-tagline" d="M488,88.22h2.49v4.09h2.34v2h-2.34v9.56a1,1,0,0,0,.52,1,2.19,2.19,0,0,0,.95.15h.39l.48,0v2a4.39,4.39,0,0,1-.89.18,7.52,7.52,0,0,1-1,.06,2.69,2.69,0,0,1-2.34-.88A3.94,3.94,0,0,1,488,104v-9.7h-2v-2h2Z" />
-                                  <path class="cls-8 app-tagline" d="M503.47,92.9a6.78,6.78,0,0,1,1.41,1.39V92.45h2.27v13.32a10,10,0,0,1-.81,4.4c-1,2-2.94,3-5.77,3a7.09,7.09,0,0,1-4-1.06,4.1,4.1,0,0,1-1.8-3.32h2.5a2.74,2.74,0,0,0,.71,1.52,3.57,3.57,0,0,0,2.61.82c1.87,0,3.1-.66,3.68-2a11.37,11.37,0,0,0,.48-4.2,4.84,4.84,0,0,1-1.77,1.67,6,6,0,0,1-2.74.54,5.83,5.83,0,0,1-4.15-1.69q-1.77-1.68-1.77-5.58a8.43,8.43,0,0,1,1.79-5.74,5.51,5.51,0,0,1,4.32-2.07A5.38,5.38,0,0,1,503.47,92.9Zm.3,2.64a3.56,3.56,0,0,0-2.85-1.31,3.5,3.5,0,0,0-3.53,2.43,9.48,9.48,0,0,0-.51,3.4,6.12,6.12,0,0,0,1,3.77,3.24,3.24,0,0,0,2.69,1.29,3.75,3.75,0,0,0,3.71-2.39,7.71,7.71,0,0,0,.6-3.16A6.14,6.14,0,0,0,503.77,95.54Z" />
-                                  <path class="cls-8 app-tagline" d="M511,92.31h2.33v2.53a5.91,5.91,0,0,1,1.41-1.8A3.69,3.69,0,0,1,517.3,92l.23,0,.56,0v2.6a2.08,2.08,0,0,0-.4-.05l-.41,0a3.48,3.48,0,0,0-2.85,1.2,4.14,4.14,0,0,0-1,2.75V107H511Z" />
-                                  <path class="cls-8 app-tagline" d="M529.27,92.72a5.44,5.44,0,0,1,2.21,1.89,6.52,6.52,0,0,1,1,2.58,16.6,16.6,0,0,1,.22,3.23H522a6.34,6.34,0,0,0,1,3.59,3.49,3.49,0,0,0,3,1.35,3.9,3.9,0,0,0,3-1.28,4.37,4.37,0,0,0,.9-1.72h2.42a5,5,0,0,1-.63,1.8,6.34,6.34,0,0,1-1.21,1.62,5.71,5.71,0,0,1-2.75,1.48,8.65,8.65,0,0,1-2,.21,6.11,6.11,0,0,1-4.6-2,7.79,7.79,0,0,1-1.89-5.58,8.41,8.41,0,0,1,1.9-5.72,6.26,6.26,0,0,1,5-2.21A6.59,6.59,0,0,1,529.27,92.72Zm.88,5.74a6.46,6.46,0,0,0-.69-2.55,3.54,3.54,0,0,0-3.35-1.78,3.72,3.72,0,0,0-2.82,1.22,4.69,4.69,0,0,0-1.21,3.11Z" />
-                                  <path class="cls-8 app-tagline" d="M537.9,100.47a5.6,5.6,0,0,0,.78,2.78q1.3,2,4.59,2a7.9,7.9,0,0,0,2.69-.44,3.09,3.09,0,0,0,2.34-3,2.64,2.64,0,0,0-1-2.33,9.55,9.55,0,0,0-3.15-1.19l-2.64-.62a11.41,11.41,0,0,1-3.65-1.33A4.23,4.23,0,0,1,536,92.54a5.86,5.86,0,0,1,1.83-4.44A7.16,7.16,0,0,1,543,86.37a8.75,8.75,0,0,1,5.22,1.52,5.57,5.57,0,0,1,2.15,4.87h-2.56a5.12,5.12,0,0,0-.84-2.47c-.79-1.05-2.14-1.57-4.05-1.57a4.51,4.51,0,0,0-3.31,1,3.2,3.2,0,0,0-1,2.35,2.33,2.33,0,0,0,1.19,2.16,16.76,16.76,0,0,0,3.54,1.09l2.73.65a8.15,8.15,0,0,1,3,1.27,4.81,4.81,0,0,1,1.86,4.09,5.14,5.14,0,0,1-2.37,4.77,10.46,10.46,0,0,1-5.5,1.43,8.07,8.07,0,0,1-5.72-1.91,6.57,6.57,0,0,1-2-5.16Z" />
-                                  <path class="cls-8 app-tagline" d="M573.17,106.9l-1.36,1.65-3.11-2.36a11.33,11.33,0,0,1-2.43,1,10.29,10.29,0,0,1-2.85.37,9.18,9.18,0,0,1-7.32-3.06A11.71,11.71,0,0,1,553.76,97a11.9,11.9,0,0,1,2-7,8.78,8.78,0,0,1,7.69-3.72c3.54,0,6.17,1.14,7.87,3.42a11.08,11.08,0,0,1,2,6.82,14.28,14.28,0,0,1-.48,3.73,9.67,9.67,0,0,1-2.44,4.46ZM565.35,105a3.36,3.36,0,0,0,1.29-.47l-2.22-1.72,1.37-1.68,2.62,2A7.5,7.5,0,0,0,570.1,100a13.76,13.76,0,0,0,.45-3.39,8.48,8.48,0,0,0-1.85-5.7,6.35,6.35,0,0,0-5.07-2.17,6.6,6.6,0,0,0-5.15,2.08q-1.9,2.07-1.9,6.38A8.64,8.64,0,0,0,558.4,103a6.63,6.63,0,0,0,5.36,2.15A11.24,11.24,0,0,0,565.35,105Z" />
-                                  <path class="cls-8 app-tagline" d="M576.58,86.87h2.72v17.69h10.08V107h-12.8Z" />
-                                  <line class="cls-9 app-name-underline" x1="219.17" y1="66.5" x2="384.17" y2="66.5" />
-                               </g>
-                            </svg>
-                        </div>
-                        <h4>{{ _('Feature rich') }} | {{ _('Maximises PostgreSQL') }} | {{ _('Open Source') }} </h4>
-                        <p>
-                            {{ _('pgAdmin is an Open Source administration and management tool for the PostgreSQL database. It includes a graphical administration interface, an SQL query tool, a procedural code debugger and much more. The tool is designed to answer the needs of developers, DBAs and system administrators alike.') }}
-                        </p>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card ">
-                    <div class="card-header">{{ _('Quick Links') }}</div>
-                    <div class="card-body p-2">
-                        <div class="row">
-                            <div class="col-6 dashboard-link">
-                                <a href="#" onclick="pgAdmin.Dashboard.add_new_server()">
-                                    <span class="fa fa-4x dashboard-icon fa-server" aria-hidden="true"></span><br/>
-                                    {{ _('Add New Server') }}
-                                </a>
-                            </div>
-                            <div class="col-6 dashboard-link">
-                                <a href="#" onclick="pgAdmin.Preferences.show()">
-                                    <span id="mnu_preferences" class="fa fa-4x dashboard-icon fa-cogs"
-                                          aria-hidden="true"></span><br/>
-                                    {{ _('Configure pgAdmin') }}
-                                </a>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="row mb-2">
-            <div class="col-12">
-                <div class="card ">
-                    <div class="card-header">{{ _('Getting Started') }}</div>
-                    <div class="card-body p-2">
-                        <div class="row">
-                        <div class="col-3 dashboard-link">
-                            <a href="http://www.postgresql.org/docs" target="postgres_help">
-                                <span class="fa fa-4x dashboard-icon dashboard-pg-doc" aria-hidden="true"></span><br/>
-                                {{ _('PostgreSQL Documentation') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="https://www.pgadmin.org" target="pgadmin_website">
-                                <span class="fa fa-4x dashboard-icon fa-globe" aria-hidden="true"></span><br/>
-                                {{ _('pgAdmin Website') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="http://planet.postgresql.org" target="planet_website">
-                                <span class="fa fa-4x dashboard-icon fa-book" aria-hidden="true"></span><br/>
-                                {{ _('Planet PostgreSQL') }}
-                            </a>
-                        </div>
-                        <div class="col-3 dashboard-link">
-                            <a href="http://www.postgresql.org/community" target="postgres_website">
-                                <span class="fa fa-4x dashboard-icon fa-users" aria-hidden="true"></span><br/>
-                                {{ _('Community Support') }}
-                            </a>
-                        </div>
-                    </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
diff --git a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
index ee7ea6e46..ccb605d67 100644
--- a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
+++ b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
@@ -16,6 +16,7 @@ import Notify from '../../../../static/js/helpers/Notifier';
 import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import { getURL } from '../../../static/utils/utils';
+import Loader from 'sources/components/Loader';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
@@ -71,7 +72,7 @@ function parseData(data, node) {
 export default function Dependencies({ nodeData, item, node, ...props }) {
   const classes = useStyles();
   const [tableData, setTableData] = React.useState([]);
-
+  const [loaderText, setLoaderText] = React.useState('');
   const [msg, setMsg] = React.useState('');
   var columns = [
     {
@@ -79,14 +80,14 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
       accessor: 'type',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Name',
       accessor: 'name',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Restriction',
@@ -114,7 +115,7 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
       );
       if (node.hasDepends) {
         const api = getApiInstance();
-
+        setLoaderText('Loading...');
         api({
           url: url,
           type: 'GET',
@@ -123,8 +124,10 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
             if (res.data.length > 0) {
               let data = parseData(res.data, node);
               setTableData(data);
+              setLoaderText('');
             } else {
               setMsg(message);
+              setLoaderText('');
             }
           })
           .catch((e) => {
@@ -157,10 +160,12 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
         ></PgTable>
       ) : (
         <div className={classes.emptyPanel}>
-          <div className={classes.panelIcon}>
-            <i className="fa fa-exclamation-circle"></i>
-            <span className={classes.panelMessage}>{gettext(msg)}</span>
-          </div>
+          {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          }
         </div>
       )}
     </>
diff --git a/web/pgadmin/misc/dependents/static/js/Dependents.jsx b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
index 487e2d29b..867368b97 100644
--- a/web/pgadmin/misc/dependents/static/js/Dependents.jsx
+++ b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
@@ -16,6 +16,7 @@ import Notify from '../../../../static/js/helpers/Notifier';
 import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import { getURL } from '../../../static/utils/utils';
+import Loader from 'sources/components/Loader';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
@@ -71,7 +72,7 @@ function parseData(data, node) {
 export default function Dependents({ nodeData, item, node, ...props }) {
   const classes = useStyles();
   const [tableData, setTableData] = React.useState([]);
-
+  const [loaderText, setLoaderText] = React.useState('');
   const [msg, setMsg] = React.useState('');
 
   var columns = [
@@ -80,14 +81,14 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       accessor: 'type',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Name',
       accessor: 'name',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Restriction',
@@ -115,6 +116,7 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       );
       if (node.hasDepends && !nodeData.is_collection) {
         const api = getApiInstance();
+        setLoaderText('Loading...');
         api({
           url: url,
           type: 'GET',
@@ -125,6 +127,7 @@ export default function Dependents({ nodeData, item, node, ...props }) {
               setTableData(data);
             } else {
               setMsg(message);
+              setLoaderText('');
             }
           })
           .catch((e) => {
@@ -158,11 +161,15 @@ export default function Dependents({ nodeData, item, node, ...props }) {
         ></PgTable>
       ) : (
         <div className={classes.emptyPanel}>
-          <div className={classes.panelIcon}>
-            <i className="fa fa-exclamation-circle"></i>
-            <span className={classes.panelMessage}>{gettext(msg)}</span>
-          </div>
+          {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
+
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          }
         </div>
+
       )}
     </>
   );
diff --git a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
new file mode 100644
index 000000000..db20331a9
--- /dev/null
+++ b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
@@ -0,0 +1,331 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+import pgAdmin from 'sources/pgadmin';
+import getApiInstance from 'sources/api_instance';
+import { makeStyles } from '@material-ui/core/styles';
+import { Box, Switch } from '@material-ui/core';
+import { generateCollectionURL } from '../../browser/static/js/node_ajax';
+import Notify from '../../static/js/helpers/Notifier';
+import gettext from 'sources/gettext';
+import 'wcdocker';
+import PgTable from 'sources/components/PgTable';
+import Theme from 'sources/Theme';
+import PropTypes from 'prop-types';
+import { PgIconButton } from '../../static/js/components/Buttons';
+
+const useStyles = makeStyles((theme) => ({
+  emptyPanel: {
+    minHeight: '100%',
+    minWidth: '100%',
+    background: theme.palette.grey[400],
+    overflow: 'auto',
+    padding: '7.5px',
+  },
+  panelIcon: {
+    width: '80%',
+    margin: '0 auto',
+    marginTop: '25px !important',
+    position: 'relative',
+    textAlign: 'center',
+  },
+  panelMessage: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+  },
+  searchPadding: {
+    flex: 2.5
+  },
+  searchInput: {
+    flex: 1,
+    margin: '4 0 4 0',
+    borderLeft: 'none',
+    paddingLeft: 5
+  },
+  propertiesPanel: {
+    height: '100%'
+  },
+  autoResizer: {
+    height: '100% !important',
+    width: '100% !important',
+    background: theme.palette.grey[400],
+    padding: '8px',
+  },
+  dropButton: {
+    marginRight: '5px !important'
+  },
+  readOnlySwitch: {
+    opacity: 0.75,
+    '& .MuiSwitch-track': {
+      opacity: theme.palette.action.disabledOpacity,
+    }
+  }
+}));
+
+export function CollectionNodeView({
+  node,
+  treeNodeInfo,
+  itemNodeData,
+  item,
+  pgBrowser
+}) {
+  const classes = useStyles();
+
+  const [data, setData] = React.useState([]);
+  const [infoMsg, setInfoMsg] = React.useState('Please select an object in the tree view.');
+  const [selectedObject, setSelectedObject] = React.useState([]);
+  const [reload, setReload] = React.useState();
+
+  const [pgTableColumns, setPgTableColumns] = React.useState([
+    {
+      Header: 'properties',
+      accessor: 'Properties',
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+    {
+      Header: 'value',
+      accessor: 'value',
+      sortble: true,
+      resizable: false,
+      disableGlobalFilter: false,
+    },
+  ]);
+
+  const getTableSelectedRows = (selRows) => {
+    setSelectedObject(selRows);
+  };
+
+  const onDrop = (type) => {
+    let selRowModels = selectedObject,
+      selRows = [],
+      selItem = pgBrowser.tree.selected(),
+      selectedItemData = selItem ? pgBrowser.tree.itemData(selItem) : null,
+      selNode = selectedItemData && pgBrowser.Nodes[selectedItemData._type],
+      url = undefined,
+      msg = undefined,
+      title = undefined;
+
+    if (selNode && selNode.type && selNode.type == 'coll-constraints') {
+      // In order to identify the constraint type, the type should be passed to the server
+      selRows = selRowModels.map((row) => ({
+        id: row.get('oid'),
+        _type: row.get('_type'),
+      }));
+    } else {
+      selRows = selRowModels.map((row) => row.original.oid);
+    }
+
+    if (selRows.length === 0) {
+      Notify.alert(
+        gettext('Drop Multiple'),
+        gettext('Please select at least one object to delete.')
+      );
+      return;
+    }
+
+    if (!selNode) return;
+
+    if (type === 'dropCascade') {
+      url = selNode.generate_url(selItem, 'delete');
+      msg = gettext(
+        'Are you sure you want to drop all the selected objects and all the objects that depend on them?'
+      );
+      title = gettext('DROP CASCADE multiple objects?');
+    } else {
+      url = selNode.generate_url(selItem, 'drop');
+      msg = gettext('Are you sure you want to drop all the selected objects?');
+      title = gettext('DROP multiple objects?');
+    }
+
+    const api = getApiInstance();
+    let dropNodeProperties = function () {
+      api
+        .delete(url, {
+          data: JSON.stringify({ ids: selRows }),
+          contentType: 'application/json; charset=utf-8',
+        })
+        .then(function (res) {
+          if (res.success == 0) {
+            pgBrowser.report_error(res.errormsg, res.info);
+          } else {
+            pgBrowser.Events.trigger(
+              'pgadmin:browser:tree:refresh',
+              selItem || pgBrowser.tree.selected(),
+              {
+                success: function () {
+                  pgBrowser.tree.select(selItem);
+                  selNode.callbacks.selected.apply(selNode, [selItem]);
+                },
+              }
+            );
+          }
+          setReload(true);
+        })
+        .catch(function (error) {
+          Notify.error(
+            gettext('Error dropping %s', selectedItemData._label.toLowerCase()),
+            error.message
+          );
+        });
+    };
+
+    if (confirm) {
+      Notify.confirm(title, msg, dropNodeProperties, null);
+    } else {
+      dropNodeProperties();
+    }
+  };
+
+  React.useEffect(() => {
+    if (node){
+
+      let nodeObj =
+      pgAdmin.Browser.Nodes[itemNodeData?._type.replace('coll-', '')];
+
+      let schema = nodeObj.getSchema.call(nodeObj, treeNodeInfo, itemNodeData);
+      let url = generateCollectionURL.call(nodeObj, item, 'properties');
+
+      const api = getApiInstance();
+
+      let tableColumns = [];
+      var column = {};
+
+      if (itemNodeData._type.indexOf('coll-') > -1) {
+        schema.fields.forEach((field) => {
+          if (node.columns.indexOf(field.id) > -1) {
+            if (field.label.indexOf('?') > -1) {
+              column = {
+                Header: field.label,
+                accessor: field.id,
+                sortble: true,
+                resizable: false,
+                disableGlobalFilter: false,
+                // eslint-disable-next-line react/display-name
+                Cell: ({ value }) => {
+                  return (<Switch color="primary" checked={value} className={classes.readOnlySwitch} value={value} readOnly title={String(value)} />);
+                }
+              };
+            } else {
+              column = {
+                Header: field.label,
+                accessor: field.id,
+                sortble: true,
+                resizable: false,
+                disableGlobalFilter: false,
+              };
+            }
+            tableColumns.push(column);
+          }
+        });
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            res.data.forEach((element) => {
+              element['icon'] = '';
+            });
+            setPgTableColumns(tableColumns);
+            setData(res.data);
+            setInfoMsg('No properties are available for the selected object.');
+          })
+          .catch((err) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(err.message)
+            );
+          });
+      }
+    }
+  }, [itemNodeData, node, item, reload]);
+
+  const customHeader = () => {
+    return (
+      <Box >
+        <PgIconButton
+          className={classes.dropButton}
+          variant="outlined"
+          icon={<i className='fa fa-trash-alt delete_multiple' aria-hidden="true" role="img"></i>}
+          aria-label="Delete/Drop"
+          title={gettext('Delete/Drop')}
+          onClick={() => {
+            onDrop('drop');
+          }}
+          disabled={
+            (selectedObject.length > 0)
+              ? !node.canDrop
+              : true
+          }
+        ></PgIconButton>
+        <PgIconButton
+          className={classes.dropButton}
+          variant="outlined"
+          icon={<i className='pg-font-icon icon-drop_cascade delete_multiple_cascade' aria-hidden="true" role="img"></i>}
+          aria-label="Drop Cascade"
+          title={gettext('Drop Cascade')}
+          onClick={() => {
+            onDrop('dropCascade');
+          }}
+          disabled={
+            (selectedObject.length > 0)
+              ? !node.canDropCascade
+              : true
+          }
+        ></PgIconButton>
+      </Box>);
+  };
+
+  return (
+    <Theme>
+      <Box className={classes.propertiesPanel}>
+        {data.length > 0 ?
+          (
+            <PgTable
+              isSelectRow={!('catalog' in treeNodeInfo) && (itemNodeData.label !== 'Catalogs')}
+              customHeader={customHeader}
+              className={classes.autoResizer}
+              columns={pgTableColumns}
+              data={data}
+              type={'panel'}
+              isSearch={false}
+              getSelectedRows={getTableSelectedRows}
+            />
+          )
+          :
+          (
+            <div className={classes.emptyPanel}>
+              <div className={classes.panelIcon}>
+                <i className="fa fa-exclamation-circle"></i>
+                <span className={classes.panelMessage}>{gettext(infoMsg)}</span>
+              </div>
+            </div>
+
+          )
+        }
+      </Box>
+    </Theme>
+  );
+}
+
+CollectionNodeView.propTypes = {
+  node: PropTypes.func,
+  itemData: PropTypes.object,
+  itemNodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  item: PropTypes.object,
+  pgBrowser: PropTypes.object,
+  preferences: PropTypes.object,
+  sid: PropTypes.number,
+  did: PropTypes.number,
+  row: PropTypes.object,
+  serverConnected: PropTypes.bool,
+  value: PropTypes.bool,
+};
diff --git a/web/pgadmin/misc/sql/static/js/SQL.jsx b/web/pgadmin/misc/sql/static/js/SQL.jsx
new file mode 100644
index 000000000..5eec57e8d
--- /dev/null
+++ b/web/pgadmin/misc/sql/static/js/SQL.jsx
@@ -0,0 +1,114 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import React, { useEffect } from 'react';
+import { generateNodeUrl } from '../../../../browser/static/js/node_ajax';
+import gettext from 'sources/gettext';
+import PropTypes from 'prop-types';
+import Notify from '../../../../static/js/helpers/Notifier';
+import getApiInstance from 'sources/api_instance';
+import { makeStyles } from '@material-ui/core/styles';
+import CodeMirror from '../../../../static/js/components/CodeMirror';
+
+const useStyles = makeStyles((theme) => ({
+  textArea: {
+    height: '100% !important',
+    width: '100% !important',
+    background: theme.palette.grey[400],
+    overflow: 'auto !important',
+    minHeight: '100%',
+    minWidth: '100%',
+  },
+}));
+
+export default function SQL({ nodeData, node, ...props }) {
+  const classes = useStyles();
+  const [nodeSQL, setNodeSQL] = React.useState('');
+
+  const [msg, setMsg] = React.useState('');
+
+  useEffect(() => {
+    var sql = '-- ' + gettext('Please select an object in the tree view.');
+    if (node) {
+      let url = generateNodeUrl.call(
+        node,
+        props.treeNodeInfo,
+        'sql',
+        nodeData,
+        true,
+        node.url_jump_after_node
+      );
+      sql =
+        '-- ' + gettext('No SQL could be generated for the selected object.');
+
+      if (node.hasSQL) {
+        const api = getApiInstance();
+
+        api({
+          url: url,
+          type: 'GET',
+        })
+          .then((res) => {
+            if (res.data.length > 0) {
+              setNodeSQL(res.data);
+            } else {
+              setMsg(sql);
+            }
+          })
+          .catch((e) => {
+            Notify.alert(
+              gettext('Failed to retrieve data from the server.'),
+              gettext(e.message)
+            );
+            // show failed message.
+            setMsg(gettext('Failed to retrieve data from the server.'));
+          });
+      }
+    }
+    if (sql != '') {
+      setMsg(sql);
+    }
+    return () => {
+      setNodeSQL([]);
+    };
+  }, [nodeData]);
+
+  return (
+    <>
+      {nodeSQL.length > 0 ? (
+        <CodeMirror
+          className={classes.textArea}
+          value={nodeSQL}
+          options={{
+            lineNumbers: true,
+            mode: 'text/x-pgsql',
+            readOnly: true,
+          }}
+        />
+      ) : (
+        <CodeMirror
+          className={classes.textArea}
+          value={msg}
+          options={{
+            lineNumbers: true,
+            mode: 'text/x-pgsql',
+            readOnly: true,
+          }}
+        />
+      )}
+    </>
+  );
+}
+
+SQL.propTypes = {
+  res: PropTypes.array,
+  nodeData: PropTypes.object,
+  treeNodeInfo: PropTypes.object,
+  node: PropTypes.func,
+};
diff --git a/web/pgadmin/misc/sql/static/js/sql.js b/web/pgadmin/misc/sql/static/js/sql.js
deleted file mode 100644
index 57ee3129a..000000000
--- a/web/pgadmin/misc/sql/static/js/sql.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import Notify from '../../../../static/js/helpers/Notifier';
-
-define('misc.sql', [
-  'sources/gettext', 'underscore', 'jquery',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.alertifyjs',
-], function(gettext, _, $, pgAdmin, pgBrowser, Alertify) {
-
-  pgBrowser.ShowNodeSQL = pgBrowser.ShowNodeSQL || {};
-
-  if (pgBrowser.ShowNodeSQL.initialized) {
-    return pgBrowser.ShowNodeSQL;
-  }
-  var wcDocker = window.wcDocker;
-
-  _.extend(pgBrowser.ShowNodeSQL, {
-    init: function() {
-      if (this.initialized) {
-        return;
-      }
-      this.initialized = true;
-      _.bindAll(this, 'showSQL', 'sqlPanelVisibilityChanged');
-
-      var sqlPanels;
-      this.sqlPanels = sqlPanels = pgBrowser.docker.findPanels('sql');
-
-      // We will listend to the visibility change of the SQL panel
-      pgBrowser.Events.on(
-        'pgadmin-browser:panel-sql:' + wcDocker.EVENT.VISIBILITY_CHANGED,
-        this.sqlPanelVisibilityChanged
-      );
-
-      pgBrowser.Events.on(
-        'pgadmin:browser:node:updated',
-        function() {
-          if (this.sqlPanels && this.sqlPanels.length) {
-            $(this.sqlPanels[0]).data('node-prop', '');
-            this.sqlPanelVisibilityChanged(this.sqlPanels[0]);
-          }
-        }, this
-      );
-
-      // Hmm.. Did we find the SQL panel, and is it visible (opened)?
-      // If that is the case - we need to listen the browser tree selection
-      // events.
-      if (sqlPanels.length == 0) {
-        pgBrowser.Events.on(
-          'pgadmin-browser:panel-sql:' + wcDocker.EVENT.INIT,
-          function() {
-            if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) {
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:selected', this.showSQL
-              );
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:reactSelected', this.reactShowSQL
-              );
-              pgBrowser.Events.on(
-                'pgadmin-browser:tree:refreshing', this.refreshSQL, this
-              );
-            }
-          }.bind(this)
-        );
-      } else {
-        if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) {
-          pgBrowser.Events.on('pgadmin-browser:tree:selected', this.showSQL);
-          pgBrowser.Events.on('pgadmin-browser:tree:reactSelected', this.reactShowSQL);
-          pgBrowser.Events.on(
-            'pgadmin-browser:tree:refreshing', this.refreshSQL, this
-          );
-        }
-      }
-    },
-    refreshSQL: function(item, data, node) {
-      var that = this,
-        cache_flag = {
-          node_type: data._type,
-          url: node.generate_url(item, 'sql', data, true),
-        };
-
-      if (_.isEqual($(that.sqlPanels[0]).data('node-prop'), cache_flag)) {
-        // Reset the current item selection
-        $(that.sqlPanels[0]).data('node-prop', '');
-        that.showSQL(item, data, node);
-      }
-    },
-    showSQL: function(item, data, node) {
-      /**
-       * We can't start fetching the SQL immediately, it is possible - the user
-       * is just using keyboards to select the node, and just traversing
-       * through. We will wait for some time before fetching the Reversed
-       * Engineering SQL.
-       **/
-
-      this.timeout && clearTimeout(this.timeout);
-
-      var that = this;
-      this.timeout = setTimeout(
-        function() {
-          var sql = '-- ' + gettext('Please select an object in the tree view.');
-          if (node) {
-            sql = '-- ' + gettext('No SQL could be generated for the selected object.');
-            var n_type = data._type,
-              url = node.generate_url(item, 'sql', data, true),
-              treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item),
-              cache_flag = {
-                node_type: n_type,
-                url: url,
-              };
-
-            // Avoid unnecessary reloads
-            if (_.isEqual($(that.sqlPanels[0]).data('node-prop'), cache_flag)) {
-              return;
-            }
-            // Cache the current IDs for next time
-            $(that.sqlPanels[0]).data('node-prop', cache_flag);
-
-            if (node.hasSQL) {
-
-              sql = '';
-              var timer;
-              var ajaxHook = function() {
-                $.ajax({
-                  url: url,
-                  type: 'GET',
-                  beforeSend: function(xhr) {
-                    xhr.setRequestHeader(
-                      pgAdmin.csrf_token_header, pgAdmin.csrf_token
-                    );
-                    // Generate a timer for the request
-                    timer = setTimeout(function() {
-                      // Notify user if request is taking longer than 1 second
-                      pgAdmin.Browser.editor.setValue(
-                        gettext('Retrieving data from the server...')
-                      );
-                    }, 1000);
-                  },
-                }).done(function(res) {
-                  if (pgAdmin.Browser.editor.getValue() != res) {
-                    pgAdmin.Browser.editor.setValue(res);
-                  }
-                  clearTimeout(timer);
-                }).fail(function(xhr, error, message) {
-                  var _label = treeHierarchy[n_type].label;
-                  pgBrowser.Events.trigger(
-                    'pgadmin:node:retrieval:error', 'sql', xhr, error, message, item
-                  );
-                  if (!Alertify.pgHandleItemError(xhr, error, message, {
-                    item: item,
-                    info: treeHierarchy,
-                  })) {
-                    Notify.pgNotifier(
-                      error, xhr,
-                      gettext('Error retrieving the information - %s', message || _label),
-                      function(msg) {
-                        if(msg === 'CRYPTKEY_SET') {
-                          ajaxHook();
-                        } else {
-                          console.warn(arguments);
-                        }
-                      }
-                    );
-                  }
-                });
-              };
-              ajaxHook();
-            }
-          }
-
-          if (sql != '') {
-            pgAdmin.Browser.editor.setValue(sql);
-          }
-        }, 400);
-    },
-    sqlPanelVisibilityChanged: function(panel) {
-      if (panel.isVisible()) {
-        var t = pgBrowser.tree,
-          i = t.selected(),
-          d = i && t.itemData(i),
-          n = i && d && pgBrowser.Nodes[d._type];
-
-        pgBrowser.ShowNodeSQL.showSQL.apply(pgBrowser.ShowNodeSQL, [i, d, n]);
-
-        // We will start listening the tree selection event.
-        pgBrowser.Events.on('pgadmin-browser:tree:selected', pgBrowser.ShowNodeSQL.showSQL);
-        pgBrowser.Events.on(
-          'pgadmin-browser:tree:refreshing', pgBrowser.ShowNodeSQL.refreshSQL, this
-        );
-      } else {
-        // We don't need to listen the tree item selection event.
-        pgBrowser.Events.off('pgadmin-browser:tree:selected', pgBrowser.ShowNodeSQL.showSQL);
-        pgBrowser.Events.off(
-          'pgadmin-browser:tree:refreshing', pgBrowser.ShowNodeSQL.refreshSQL, this
-        );
-      }
-    },
-  });
-
-  return pgBrowser.ShowNodeSQL;
-});
diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
index caf635351..305262680 100644
--- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx
+++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
@@ -17,7 +17,7 @@ import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import sizePrettify from 'sources/size_prettify';
 import { getURL } from '../../../static/utils/utils';
-
+import Loader from 'sources/components/Loader';
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
@@ -37,12 +37,18 @@ const useStyles = makeStyles((theme) => ({
     marginLeft: '0.5rem',
     fontSize: '0.875rem',
   },
+  loading: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+    colour: theme.palette.grey[400]
+  },
   autoResizer: {
     height: '100% !important',
     width: '100% !important',
     background: theme.palette.grey[400],
     padding: '7.5px',
-    overflow: 'auto !important',
+    overflowX: 'auto !important',
+    overflowY: 'hidden !important',
     minHeight: '100%',
     minWidth: '100%',
   },
@@ -58,7 +64,7 @@ function getColumn(data, singleLineStatistics) {
           accessor: row.name,
           sortble: true,
           resizable: false,
-          disableGlobalFilter: true,
+          disableGlobalFilter: false,
         };
         columns.push(column);
       });
@@ -71,14 +77,14 @@ function getColumn(data, singleLineStatistics) {
         accessor: 'name',
         sortble: true,
         resizable: false,
-        disableGlobalFilter: true,
+        disableGlobalFilter: false,
       },
       {
         Header: 'Value',
         accessor: 'value',
         sortble: true,
         resizable: false,
-        disableGlobalFilter: true,
+        disableGlobalFilter: false,
       },
     ];
   }
@@ -142,20 +148,21 @@ export default function Statistics({ nodeData, item, node, ...props }) {
   const [tableData, setTableData] = React.useState([]);
 
   const [msg, setMsg] = React.useState('');
+  const [loaderText, setLoaderText] = React.useState('');
   const [columns, setColumns] = React.useState([
     {
       Header: 'Statictics',
       accessor: 'name',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
     {
       Header: 'Value',
       accessor: 'value',
       sortble: true,
       resizable: false,
-      disableGlobalFilter: true,
+      disableGlobalFilter: false,
     },
   ]);
 
@@ -170,6 +177,7 @@ export default function Statistics({ nodeData, item, node, ...props }) {
 
       const api = getApiInstance();
       if (node.hasStatistics) {
+        setLoaderText('Loading...');
         api({
           url: url,
           type: 'GET',
@@ -180,6 +188,7 @@ export default function Statistics({ nodeData, item, node, ...props }) {
             if (!_.isUndefined(colData)) {
               setColumns(colData);
             }
+            setLoaderText('');
           })
           .catch((e) => {
             Notify.alert(
@@ -187,10 +196,12 @@ export default function Statistics({ nodeData, item, node, ...props }) {
               gettext(e.message)
             );
             // show failed message.
+            setLoaderText('');
             setMsg(gettext('Failed to retrieve data from the server.'));
           });
       } else {
-        setMsg(message);
+        setLoaderText('');
+        setMsg('No statistics are available for the selected object.');
       }
     }
     if (message != '') {
@@ -213,10 +224,12 @@ export default function Statistics({ nodeData, item, node, ...props }) {
         ></PgTable>
       ) : (
         <div className={classes.emptyPanel}>
-          <div className={classes.panelIcon}>
-            <i className="fa fa-exclamation-circle"></i>
-            <span className={classes.panelMessage}>{gettext(msg)}</span>
-          </div>
+          {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
+            <div className={classes.panelIcon}>
+              <i className="fa fa-exclamation-circle"></i>
+              <span className={classes.panelMessage}>{gettext(msg)}</span>
+            </div>
+          }
         </div>
       )}
     </>
diff --git a/web/pgadmin/static/js/Theme/dark.js b/web/pgadmin/static/js/Theme/dark.js
index 0fd5cc5a4..cafaaae3e 100644
--- a/web/pgadmin/static/js/Theme/dark.js
+++ b/web/pgadmin/static/js/Theme/dark.js
@@ -92,7 +92,8 @@ export default function(basicSettings) {
       activeStepFg: '#FFFFFF',
       stepBg: '#FFFFFF',
       stepFg: '#000',
-      toggleBtnBg: '#000'
+      toggleBtnBg: '#000',
+      colorFg: '#FFFFFF',
     }
   });
 }
diff --git a/web/pgadmin/static/js/Theme/high_contrast.js b/web/pgadmin/static/js/Theme/high_contrast.js
index b567ca23e..a9c172ac7 100644
--- a/web/pgadmin/static/js/Theme/high_contrast.js
+++ b/web/pgadmin/static/js/Theme/high_contrast.js
@@ -90,7 +90,8 @@ export default function(basicSettings) {
       activeStepFg: '#010b15',
       stepBg: '#FFFFFF',
       stepFg: '#000',
-      toggleBtnBg: '#6B6B6B'
+      toggleBtnBg: '#6B6B6B',
+      colorFg: '#FFFFFF',
     }
   });
 }
diff --git a/web/pgadmin/static/js/Theme/standard.js b/web/pgadmin/static/js/Theme/standard.js
index ddc9cd735..8cf463a71 100644
--- a/web/pgadmin/static/js/Theme/standard.js
+++ b/web/pgadmin/static/js/Theme/standard.js
@@ -85,6 +85,7 @@ export default function(basicSettings) {
         padding: '5px 8px',
       },
       borderColor: '#dde0e6',
+      colorFg: '#222222',
       loader: {
         backgroundColor: fade('#000', 0.65),
         color: '#fff',
@@ -102,6 +103,7 @@ export default function(basicSettings) {
       toggleBtnBg: '#000',
       editorToolbarBg: '#ebeef3',
       datagridBg: '#fff',
+
     }
   });
 }
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index 1b5179ac0..b6f9d12cb 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -8,13 +8,26 @@
 //////////////////////////////////////////////////////////////
 
 import React from 'react';
-import { useTable, useRowSelect, useSortBy, useResizeColumns, useFlexLayout, useGlobalFilter } from 'react-table';
-import { FixedSizeList } from 'react-window';
+import {
+  useTable,
+  useRowSelect,
+  useSortBy,
+  useResizeColumns,
+  useFlexLayout,
+  useGlobalFilter,
+  useExpanded,
+} from 'react-table';
+import { VariableSizeList } from 'react-window';
 import { makeStyles } from '@material-ui/core/styles';
 import clsx from 'clsx';
 import PropTypes from 'prop-types';
 import AutoSizer from 'react-virtualized-auto-sizer';
-import { Checkbox } from '@material-ui/core';
+import { Checkbox, Box } from '@material-ui/core';
+import { InputText } from './FormComponents';
+import FormView from 'sources/SchemaView';
+import _ from 'lodash';
+import gettext from 'sources/gettext';
+
 /* eslint-disable react/display-name */
 const useStyles = makeStyles((theme) => ({
   root: {
@@ -29,22 +42,56 @@ const useStyles = makeStyles((theme) => ({
     width: '100% !important',
   },
   fixedSizeList: {
-    // position: 'relative',
     direction: 'ltr',
     overflowX: 'hidden !important',
-    overflow: 'overlay !important'
+    overflow: 'overlay !important',
+  },
+  customHeader:{
+    marginTop: '12px',
+    marginLeft: '4px'
+  },
+  searchBox: {
+    marginBottom: '5px',
+    display: 'flex',
+    background: theme.palette.background.default
+  },
+  tableContentWidth: {
+    width: 'calc(100% - 3px)',
+  },
+  searchPadding: {
+    flex: 2.5
+  },
+  searchInput: {
+    flex: 1,
+    marginTop: 8,
+    borderLeft: 'none',
+    paddingLeft: 5,
+    marginRight: 8,
+    marginBottom: 8,
+
   },
   table: {
-    flexGrow:1,
-    minHeight:0,
+    flexGrow: 1,
+    minHeight: 0,
     borderSpacing: 0,
     width: '100%',
     overflow: 'hidden',
     borderRadius: theme.shape.borderRadius,
+    border: '1px solid'+ theme.palette.grey[400]
   },
-  extraTable:{
-    backgroundColor: theme.palette.grey[400],
-    flexGrow:1,
+  pgTableHeadar: {
+    display: 'flex',
+    flexGrow: 1,
+    overflow: 'hidden !important',
+    height: '100% !important',
+    flexDirection: 'column'
+  },
+
+  expandedForm: {
+    ...theme.mixins.panelBorder,
+    margin: '8px',
+    paddingBottom: '12px',
+    marginRight: '15px',
   },
 
   tableCell: {
@@ -54,15 +101,14 @@ const useStyles = makeStyles((theme) => ({
     ...theme.mixins.panelBorder.right,
     position: 'relative',
     overflow: 'hidden',
+    height: '35px',
     textOverflow: 'ellipsis',
     whiteSpace: 'nowrap',
     backgroundColor: theme.otherVars.tableBg,
-    // ...theme.mixins.panelBorder.top,
-    ...theme.mixins.panelBorder.left,
-
   },
   selectCell: {
-    textAlign: 'center'
+    textAlign: 'center',
+    minWidth: '25px'
   },
   tableCellHeader: {
     fontWeight: theme.typography.fontWeightBold,
@@ -93,13 +139,57 @@ const useStyles = makeStyles((theme) => ({
     paddingTop: '0.35em',
     height: 35,
     backgroundPosition: '1%',
-  }
-}),
-);
+  },
+  emptyPanel: {
+    minHeight: '100%',
+    minWidth: '100%',
+    background: theme.palette.background.default,
+    overflow: 'auto',
+    padding: '7.5px',
+  },
+  panelIcon: {
+    width: '80%',
+    margin: '0 auto',
+    marginTop: '25px !important',
+    position: 'relative',
+    textAlign: 'center',
+  },
+  panelMessage: {
+    marginLeft: '0.5rem',
+    fontSize: '0.875rem',
+  },
+  expandedIconCell: {
+    backgroundColor: theme.palette.grey[400],
+    ...theme.mixins.panelBorder.top,
+    borderBottom: 'none',
+  },
+  btnCell: {
+    padding: theme.spacing(0.5, 0),
+    textAlign: 'center',
+  },
+}));
 
-export default function PgTable({ columns, data, isSelectRow, ...props }) {
+export default function PgTable({ columns, data, isSelectRow, offset=105, ...props }) {
   // Use the state and functions returned from useTable to build your UI
   const classes = useStyles();
+  const [searchVal, setSearchVal] = React.useState('');
+  const tableRef = React.useRef();
+  const rowHeights = React.useRef({});
+  const rowRef = React.useRef({});
+
+  function getRowHeight(index, size) {
+    return rowHeights.current[index] + size || 35;
+  }
+
+  const setRowHeight = React.useCallback((index, size) => {
+    if(tableRef.current) {
+      tableRef.current.resetAfterIndex(index);
+      if (!(rowHeights.current.hasOwnProperty(index))){
+        rowHeights.current = { ...rowHeights.current, [index]: size };
+      }
+    }
+  }, []);
+
   const defaultColumn = React.useMemo(
     () => ({
       minWidth: 150,
@@ -119,7 +209,8 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
         <>
           <Checkbox
             color="primary"
-            ref={resolvedRef} {...rest} />
+            ref={resolvedRef} {...rest}
+          />
         </>
       );
     },
@@ -141,9 +232,9 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     rows,
     prepareRow,
     selectedFlatRows,
-    state: { selectedRowIds },
+    state: { selectedRowIds, expanded },
     setGlobalFilter,
-    setHiddenColumns
+    setHiddenColumns,
   } = useTable(
     {
       columns,
@@ -153,11 +244,12 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     },
     useGlobalFilter,
     useSortBy,
+    useExpanded,
     useRowSelect,
     useResizeColumns,
     useFlexLayout,
-    hooks => {
-      hooks.visibleColumns.push(CLOUMNS => {
+    (hooks) => {
+      hooks.visibleColumns.push((CLOUMNS) => {
         if (isSelectRow) {
           return [
             // Let's make a column for selection
@@ -178,7 +270,7 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
                 </div>
               ),
               sortble: false,
-              width: 50,
+              width: 30,
               minWidth: 0,
             },
             ...CLOUMNS,
@@ -195,11 +287,16 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
     }
   );
 
+  React.useEffect(()=>{
+    tableRef.current?.resetAfterIndex(0);
+  },[expanded]);
+
+
   React.useEffect(() => {
     setHiddenColumns(
       columns
         .filter((column) => {
-          if (column.isVisible === undefined || columns.isVisible === true) {
+          if (column.isVisible === undefined || column.isVisible === true) {
             return false;
           }
           return true;
@@ -222,28 +319,44 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
   }, [selectedRowIds]);
 
   React.useEffect(() => {
-    setGlobalFilter(props.searchText || undefined);
-  }, [props.searchText]);
-
+    setGlobalFilter(searchVal || undefined);
+  }, [searchVal]);
 
   const RenderRow = React.useCallback(
     ({ index, style }) => {
       const row = rows[index];
       prepareRow(row);
       return (
-        <div
-          {...row.getRowProps({
-            style,
-          })}
-          className={classes.tr}
-        >
-          {row.cells.map((cell) => {
-            return (
-              <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classes.tableCell, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={cell.value}>
-                {cell.render('Cell')}
-              </div>
-            );
-          })}
+        <div className={classes.tableContentWidth} style={style} key={row.id}>
+          <div {...row.getRowProps()} className={classes.tr}>
+            {row.cells.map((cell) => {
+              let classNames = [classes.tableCell];
+              if(typeof(cell.column.id) == 'string' && cell.column.id.startsWith('btn-')) {
+                classNames.push(classes.btnCell);
+              }
+              if(cell.column.id == 'btn-edit' && row.isExpanded) {
+                classNames.push(classes.expandedIconCell);
+              }
+              return (
+                <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classNames, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={String(cell.value)}>
+                  {cell.render('Cell')}
+                </div>
+              );
+            })}
+          </div>
+          {!_.isUndefined(row) && row.isExpanded && (
+            <Box key={row.id} className={classes.expandedForm} ref={rowRef} style={{height: rowHeights.current[index]}}>
+              <FormView
+                getInitData={() => {
+                  /*This is intentional (SonarQube)*/
+                }}
+                viewHelperProps={{ mode: 'properties' }}
+                schema={props.schema[row.id]}
+                showFooter={false}
+                onDataChange={() => { }}
+              />
+            </Box>
+          )}
         </div>
       );
     },
@@ -251,70 +364,108 @@ export default function PgTable({ columns, data, isSelectRow, ...props }) {
   );
   // Render the UI for your table
   return (
-    <AutoSizer className={(props.type ==='panel' ? props.className: classes.autoResizer)}>
-      {({ height}) => (
-        <div {...getTableProps()} className={classes.table}>
-          <div>
-            {headerGroups.map((headerGroup) => (
-              <div key={''} {...headerGroup.getHeaderGroupProps()}>
-                {headerGroup.headers.map((column) => (
-                  <div
-                    key={column.id}
-                    {...column.getHeaderProps()}
-                    className={clsx(
-                      classes.tableCellHeader,
-                      column.className
-                    )}
-                  >
+    <Box className={classes.pgTableHeadar}>
+      <Box className={classes.searchBox}>
+        {props.customHeader && (<Box className={classes.customHeader}> <props.customHeader /></Box>)}
+        <Box className={classes.searchPadding}></Box>
+        <InputText
+          placeholder={'Search'}
+          className={classes.searchInput}
+          value={searchVal}
+          onChange={(val) => {
+            setSearchVal(val);
+          }}
+        />
+      </Box>
+      <AutoSizer
+        className={props.type === 'panel' ? props.className : classes.autoResizer}
+      >
+        {({ height }) => (
+          <div {...getTableProps()} className={classes.table}>
+            <div>
+              {headerGroups.map((headerGroup) => (
+                <div key={''} {...headerGroup.getHeaderGroupProps()}>
+                  {headerGroup.headers.map((column) => (
                     <div
-                      {...(column.sortble
-                        ? column.getSortByToggleProps()
-                        : {})}
+                      key={column.id}
+                      {...column.getHeaderProps()}
+                      className={clsx(classes.tableCellHeader, column.className)}
                     >
-                      {column.render('Header')}
-                      <span>
-                        {column.isSorted
-                          ? column.isSortedDesc
-                            ? ' 🔽'
-                            : ' 🔼'
-                          : ''}
-                      </span>
-                      {column.resizable && (
-                        <div
-                          {...column.getResizerProps()}
-                          className={classes.resizer}
-                        />
-                      )}
+                      <div
+                        {...(column.sortble ? column.getSortByToggleProps() : {})}
+                      >
+                        {column.render('Header')}
+                        <span>
+                          {column.isSorted
+                            ? column.isSortedDesc
+                              ? ' 🔽'
+                              : ' 🔼'
+                            : ''}
+                        </span>
+                        {column.resizable && (
+                          <div
+                            {...column.getResizerProps()}
+                            className={classes.resizer}
+                          />
+                        )}
+                      </div>
                     </div>
+                  ))}
+                </div>
+              ))}
+            </div>
+
+            {
+              data.length > 0 ? (
+                <div {...getTableBodyProps()} >
+                  <VariableSizeList
+                    ref={tableRef}
+                    className={props.type === 'dashboard' ? props.fixedSizeList : classes.fixedSizeList}
+                    height={height - offset}
+                    itemCount={rows.length}
+                    itemSize={(i) => {
+                      if (_.isUndefined(rows[i].isExpanded)) {
+                        rows[i].isExpanded = false;
+                      }
+                      if (rowRef.current && rows[i].isExpanded) {
+                        setRowHeight(i, rowRef.current.offsetHeight + 35);
+                      }
+                      return rows[i].isExpanded ? getRowHeight(i, 35) : 35;
+                    }}
+                    sorted={props?.sortOptions}
+                  >
+                    {RenderRow}
+
+                  </VariableSizeList>
+                </div>
+              ) : (
+
+                <div className={classes.emptyPanel}>
+                  <div className={classes.panelIcon}>
+                    <i className="fa fa-exclamation-circle"></i>
+                    <span className={classes.panelMessage}>{gettext('No record found')}</span>
                   </div>
-                ))}
-                {/* <span className={classes.extraTable}></span> */}
-              </div>
-            ))}
-          </div>
 
-          <div {...getTableBodyProps()} className={classes}>
-            <FixedSizeList
-              className={classes.fixedSizeList}
-              height={height - 75}
-              itemCount={rows.length}
-              itemSize={35} 
-              sorted={props?.sortOptions}
-            >
-              {RenderRow}
-            </FixedSizeList>
+                </div>
+              )}
           </div>
-        </div>
-      )}
-    </AutoSizer>
+        )}
+      </AutoSizer>
+    </Box>
   );
 }
 
 PgTable.propTypes = {
   stepId: PropTypes.number,
   height: PropTypes.number,
+  offset: PropTypes.number,
+  customHeader: PropTypes.func,
   className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
-  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
+  fixedSizeList: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
+  children: PropTypes.oneOfType([
+    PropTypes.arrayOf(PropTypes.node),
+    PropTypes.node,
+  ]),
   getToggleAllRowsSelectedProps: PropTypes.func,
   columns: PropTypes.array,
   data: PropTypes.array,
@@ -324,8 +475,6 @@ PgTable.propTypes = {
   getSelectedRows: PropTypes.func,
   searchText: PropTypes.string,
   type: PropTypes.string,
-  sortOptions:  PropTypes.array,
-
+  sortOptions: PropTypes.array,
+  schema: PropTypes.object
 };
-
-
diff --git a/web/pgadmin/static/js/nodes/dashboard.js b/web/pgadmin/static/js/nodes/dashboard.js
deleted file mode 100644
index 83b87bf99..000000000
--- a/web/pgadmin/static/js/nodes/dashboard.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {isString, isFunction} from 'sources/utils';
-import pgBrowser from 'pgadmin.browser';
-
-
-export function url(itemData, item, treeHierarchy) {
-  let treeNode = pgBrowser.tree.findNodeByDomElement(item);
-  let return_url = null;
-
-  if (treeNode) {
-    treeNode.anyFamilyMember(
-      (node) => {
-        let nodeData = node.getData();
-        let browserNode = pgBrowser.Nodes[nodeData._type];
-        let dashboardURL = browserNode && browserNode.dashboard;
-
-        if (isFunction(dashboardURL)) {
-          dashboardURL = dashboardURL.apply(
-            browserNode, [node, nodeData, treeHierarchy]
-          );
-        }
-        return_url = isString(dashboardURL) ? dashboardURL : null;
-
-        return (return_url !== null);
-      });
-  }
-
-  return return_url;
-}
diff --git a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
index a0f38ea2f..015c3939d 100644
--- a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
+++ b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
@@ -17,7 +17,7 @@ import Wizard from '../../../../static/js/helpers/wizard/Wizard';
 import WizardStep from '../../../../static/js/helpers/wizard/WizardStep';
 import PgTable from 'sources/components/PgTable';
 import { getNodePrivilegeRoleSchema } from '../../../../../pgadmin/browser/server_groups/servers/static/js/privilege.ui.js';
-import { InputSQL, InputText, FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
+import { InputSQL, FormFooterMessage, MESSAGE_TYPE } from '../../../../static/js/components/FormComponents';
 import getApiInstance from '../../../../static/js/api_instance';
 import SchemaView from '../../../../static/js/SchemaView';
 import clsx from 'clsx';
@@ -117,7 +117,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
   const [selectedObject, setSelectedObject] = React.useState([]);
   const [selectedAcl, setSelectedAcl] = React.useState({});
   const [msqlData, setSQL] = React.useState('');
-  const [searchVal, setSearchVal] = React.useState('');
   const [loaderText, setLoaderText] = React.useState('');
   const [tablebData, setTableData] = React.useState([]);
   const [privOptions, setPrivOptions] = React.useState({});
@@ -314,17 +313,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
       loaderText={loaderText}
     >
       <WizardStep stepId={0}>
-        <Box className={classes.searchBox}>
-          <Box className={classes.searchPadding}></Box>
-          <InputText
-            placeholder={'Search'}
-            className={classes.searchInput}
-            value={searchVal}
-            onChange={(val) => {
-              setSearchVal(val);}
-            }>
-          </InputText>
-        </Box>
         <Box className={classes.panelContent}>
           <PgTable
             className={classes.table}
@@ -332,7 +320,6 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
             columns={columns}
             data={tablebData}
             isSelectRow={true}
-            searchText={searchVal}
             getSelectedRows={getTableSelectedRows}>
           </PgTable>
         </Box>
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 3f9c5f8f4..ed9ad4472 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -469,10 +469,8 @@ module.exports = [{
         options: {
           type: 'commonjs',
           imports: [
-            'pure|pgadmin.dashboard',
             'pure|pgadmin.browser.quick_search',
             'pure|pgadmin.tools.user_management',
-            'pure|pgadmin.browser.object_sql',
             'pure|pgadmin.browser.bgprocess',
             'pure|pgadmin.node.server_group',
             'pure|pgadmin.node.server',
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index a2e8f28e7..f9af1531f 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -208,14 +208,13 @@ var webpackShimConfig = {
     'pgadmin.browser.dialog': path.join(__dirname, './pgadmin/browser/static/js/dialog'),
     'pgadmin.browser.node': path.join(__dirname, './pgadmin/browser/static/js/node'),
     'pgadmin.browser.node.ui': path.join(__dirname, './pgadmin/browser/static/js/node.ui'),
-    'pgadmin.browser.object_sql': path.join(__dirname, './pgadmin/misc/sql/static/js/sql'),
     'pgadmin.browser.panel': path.join(__dirname, './pgadmin/browser/static/js/panel'),
     'pgadmin.browser.toolbar': path.join(__dirname, './pgadmin/browser/static/js/toolbar'),
     'pgadmin.browser.server.privilege': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/privilege'),
     'pgadmin.browser.server.variable': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/variable'),
     'pgadmin.browser.utils': '/browser/js/utils',
     'pgadmin.browser.wizard': path.join(__dirname, './pgadmin/browser/static/js/wizard'),
-    'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/dashboard'),
+    'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/Dashboard'),
     'pgadmin.datagrid': path.join(__dirname, './pgadmin/tools/datagrid/static/js/datagrid'),
     'pgadmin.file_manager': path.join(__dirname, './pgadmin/misc/file_manager/static/js/file_manager'),
     'pgadmin.file_utility': path.join(__dirname, './pgadmin/misc/file_manager/static/js/utility'),


^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-28 06:28       ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-30 06:00         ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
@ 2022-03-30 06:38           ` Akshay Joshi <[email protected]>
  2022-04-04 12:05             ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Akshay Joshi @ 2022-03-30 06:38 UTC (permalink / raw)
  To: Pradip Parkale <[email protected]>; +Cc: Aditya Toshniwal <[email protected]>; pgadmin-hackers

Thanks, the patch applied.

On Wed, Mar 30, 2022 at 11:31 AM Pradip Parkale <
[email protected]> wrote:

> Hi Akhay,
>
> Please find the updated patch.I have fixed all the issues.
>
> On Mon, Mar 28, 2022 at 11:58 AM Akshay Joshi <
> [email protected]> wrote:
>
>> Hi Pradip
>>
>> Following are the review comments (GUI):
>>
>>    - Catalog objects should not be drop or drop cascade. Remove
>>    checkboxes from the properties panel.
>>    -  Database column should be there for the 'Server Activity' table
>>    all tabs when the server is selected. When the database is selected it
>>    should be hidden.
>>    - Rename 'Lock' tab to 'Locks'.
>>    - Remove extra column 'Waiting' which was not there originally.
>>    - 'Server Activity' -> Sessions-> Details for the last record is not
>>    readable. Fix the scroll bar issue. Same with the Configuration tab last
>>    4-5 records are not readable.
>>    -  Select and expand the first and second records, the rest of the
>>    records are not visible, again seems to be a scroll bar issue.
>>    - 'Server Activity' -> Locks, "Granted?" column is empty, not showing
>>    any value.
>>    - Set the width of the column appropriately for all the tabs, for
>>    example, unit columns (in Configuration tab) width should be less, so that
>>    data on the other columns are more readable. Check all the tabs and set
>>    them appropriately
>>    - Faced "Request failed with status code 404" error. Select database
>>    server from browser tree and then select 'Server Activity'
>>    -> Configuration. Now select any database, you will get the error.
>>    - Properties panel size of the column having checkboxes should be
>>    less, compare with existing behavior.
>>    - Properties panel should show the message '*No Properties are
>>    available for the selected object*' if the respective collection node
>>    does not have children.
>>
>>
>>
>> On Mon, Mar 28, 2022 at 10:08 AM Pradip Parkale <
>> [email protected]> wrote:
>>
>>> Hi,
>>> Here is the updated patch. This patch includes the fix for #7215
>>> <https://redmine.postgresql.org/issues/7215;.
>>>
>>> On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
>>> [email protected]> wrote:
>>>
>>>> Hi Aditya,
>>>> Please ignore the previous email, find the updated patch attached.
>>>>
>>>> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Aditya,
>>>>> Please find the updated patch.
>>>>>
>>>>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Pradip,
>>>>>>
>>>>>> I did some basic usage and review and found below issues:
>>>>>> 1. The code fails if you refresh the page and go to properties, when
>>>>>> no node is selected.
>>>>>> 2. I found below UI issues on selecting a database node. Also,
>>>>>> checkbox column is too wide.
>>>>>> [image: image.png]
>>>>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>>>>
>>>>>> +
>>>>>>
>>>>>> +              ReactDOM.render(
>>>>>>
>>>>>> +                <Theme>
>>>>>>
>>>>>> +                  <CollectionNodeView
>>>>>>
>>>>>> +                    node={node}
>>>>>>
>>>>>> +                    treeNodeInfo={treeNodeInfo}
>>>>>>
>>>>>> +                    item={item}
>>>>>>
>>>>>> +                    itemNodeData={d}
>>>>>>
>>>>>> +                    pgBrowser={pgBrowser}
>>>>>>
>>>>>> +                  ></CollectionNodeView>
>>>>>>
>>>>>> +                </Theme>,
>>>>>>
>>>>>> +                b.panels['properties'].panel.$container[0]
>>>>>>
>>>>>> +              );
>>>>>>
>>>>>> 4. I have seen a lot of commented codes. Few samples:
>>>>>>
>>>>>> +              // if (that.canHide) {
>>>>>>
>>>>>>
>>>>>> +              //
>>>>>> pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
>>>>>>
>>>>>> +
>>>>>>
>>>>>> +              //     removePanelView($container[0]);
>>>>>>
>>>>>> +              // });
>>>>>>
>>>>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please move
>>>>>> it to a file and import it.
>>>>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>>>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>>>>> 8. Rename Sql.jsx to SQL.jsx
>>>>>> 9. The search is not working. It filters all.
>>>>>> 10. If there is huge data then it should show some spinner.
>>>>>> 11. Delete buttons should be disabled if no object is selected.
>>>>>> 12. Delete buttons and search box should be on the same line.
>>>>>>
>>>>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Aditya
>>>>>>>
>>>>>>> Can you please review/test it?
>>>>>>>
>>>>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Hackers,
>>>>>>>>
>>>>>>>> Please find the attached patch for #7132
>>>>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>>>>> collection, Dashboard and SQL panel in React.
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Thanks & Regards,
>>>>>>>> Pradip Parkale
>>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> *Thanks & Regards*
>>>>>>> *Akshay Joshi*
>>>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>>>
>>>>>>> *Mobile: +91 976-788-8246*
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Thanks,
>>>>>> Aditya Toshniwal
>>>>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>>>>> <http://edbpostgres.com;
>>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Thanks & Regards,
>>>>> Pradip Parkale
>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>
>>>>
>>>>
>>>> --
>>>> Thanks & Regards,
>>>> Pradip Parkale
>>>> Software Engineer | EnterpriseDB Corporation
>>>>
>>>
>>>
>>> --
>>> Thanks & Regards,
>>> Pradip Parkale
>>> Software Engineer | EnterpriseDB Corporation
>>>
>>
>>
>> --
>> *Thanks & Regards*
>> *Akshay Joshi*
>> *pgAdmin Hacker | Principal Software Architect*
>> *EDB Postgres <http://edbpostgres.com>*
>>
>> *Mobile: +91 976-788-8246*
>>
>
>
> --
> Thanks & Regards,
> Pradip Parkale
> Software Engineer | EnterpriseDB Corporation
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-28 06:28       ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-30 06:00         ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-30 06:38           ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
@ 2022-04-04 12:05             ` Pradip Parkale <[email protected]>
  2022-04-04 12:14               ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Pradip Parkale @ 2022-04-04 12:05 UTC (permalink / raw)
  To: Akshay Joshi <[email protected]>; +Cc: Aditya Toshniwal <[email protected]>; pgadmin-hackers

Hi Akshay,
Please find an updated patch. I have fixed the issue found in the testing.

On Wed, Mar 30, 2022 at 12:08 PM Akshay Joshi <[email protected]>
wrote:

> Thanks, the patch applied.
>
> On Wed, Mar 30, 2022 at 11:31 AM Pradip Parkale <
> [email protected]> wrote:
>
>> Hi Akhay,
>>
>> Please find the updated patch.I have fixed all the issues.
>>
>> On Mon, Mar 28, 2022 at 11:58 AM Akshay Joshi <
>> [email protected]> wrote:
>>
>>> Hi Pradip
>>>
>>> Following are the review comments (GUI):
>>>
>>>    - Catalog objects should not be drop or drop cascade. Remove
>>>    checkboxes from the properties panel.
>>>    -  Database column should be there for the 'Server Activity' table
>>>    all tabs when the server is selected. When the database is selected it
>>>    should be hidden.
>>>    - Rename 'Lock' tab to 'Locks'.
>>>    - Remove extra column 'Waiting' which was not there originally.
>>>    - 'Server Activity' -> Sessions-> Details for the last record is not
>>>    readable. Fix the scroll bar issue. Same with the Configuration tab last
>>>    4-5 records are not readable.
>>>    -  Select and expand the first and second records, the rest of the
>>>    records are not visible, again seems to be a scroll bar issue.
>>>    - 'Server Activity' -> Locks, "Granted?" column is empty, not
>>>    showing any value.
>>>    - Set the width of the column appropriately for all the tabs, for
>>>    example, unit columns (in Configuration tab) width should be less, so that
>>>    data on the other columns are more readable. Check all the tabs and set
>>>    them appropriately
>>>    - Faced "Request failed with status code 404" error. Select database
>>>    server from browser tree and then select 'Server Activity'
>>>    -> Configuration. Now select any database, you will get the error.
>>>    - Properties panel size of the column having checkboxes should be
>>>    less, compare with existing behavior.
>>>    - Properties panel should show the message '*No Properties are
>>>    available for the selected object*' if the respective collection
>>>    node does not have children.
>>>
>>>
>>>
>>> On Mon, Mar 28, 2022 at 10:08 AM Pradip Parkale <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>> Here is the updated patch. This patch includes the fix for #7215
>>>> <https://redmine.postgresql.org/issues/7215;.
>>>>
>>>> On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Aditya,
>>>>> Please ignore the previous email, find the updated patch attached.
>>>>>
>>>>> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Aditya,
>>>>>> Please find the updated patch.
>>>>>>
>>>>>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Pradip,
>>>>>>>
>>>>>>> I did some basic usage and review and found below issues:
>>>>>>> 1. The code fails if you refresh the page and go to properties, when
>>>>>>> no node is selected.
>>>>>>> 2. I found below UI issues on selecting a database node. Also,
>>>>>>> checkbox column is too wide.
>>>>>>> [image: image.png]
>>>>>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>>>>>
>>>>>>> +
>>>>>>>
>>>>>>> +              ReactDOM.render(
>>>>>>>
>>>>>>> +                <Theme>
>>>>>>>
>>>>>>> +                  <CollectionNodeView
>>>>>>>
>>>>>>> +                    node={node}
>>>>>>>
>>>>>>> +                    treeNodeInfo={treeNodeInfo}
>>>>>>>
>>>>>>> +                    item={item}
>>>>>>>
>>>>>>> +                    itemNodeData={d}
>>>>>>>
>>>>>>> +                    pgBrowser={pgBrowser}
>>>>>>>
>>>>>>> +                  ></CollectionNodeView>
>>>>>>>
>>>>>>> +                </Theme>,
>>>>>>>
>>>>>>> +                b.panels['properties'].panel.$container[0]
>>>>>>>
>>>>>>> +              );
>>>>>>>
>>>>>>> 4. I have seen a lot of commented codes. Few samples:
>>>>>>>
>>>>>>> +              // if (that.canHide) {
>>>>>>>
>>>>>>>
>>>>>>> +              //
>>>>>>> pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
>>>>>>>
>>>>>>> +
>>>>>>>
>>>>>>> +              //     removePanelView($container[0]);
>>>>>>>
>>>>>>> +              // });
>>>>>>>
>>>>>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please
>>>>>>> move it to a file and import it.
>>>>>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>>>>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>>>>>> 8. Rename Sql.jsx to SQL.jsx
>>>>>>> 9. The search is not working. It filters all.
>>>>>>> 10. If there is huge data then it should show some spinner.
>>>>>>> 11. Delete buttons should be disabled if no object is selected.
>>>>>>> 12. Delete buttons and search box should be on the same line.
>>>>>>>
>>>>>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Aditya
>>>>>>>>
>>>>>>>> Can you please review/test it?
>>>>>>>>
>>>>>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Hackers,
>>>>>>>>>
>>>>>>>>> Please find the attached patch for #7132
>>>>>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>>>>>> collection, Dashboard and SQL panel in React.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Thanks & Regards,
>>>>>>>>> Pradip Parkale
>>>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> *Thanks & Regards*
>>>>>>>> *Akshay Joshi*
>>>>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>>>>
>>>>>>>> *Mobile: +91 976-788-8246*
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Thanks,
>>>>>>> Aditya Toshniwal
>>>>>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>>>>>> <http://edbpostgres.com;
>>>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Thanks & Regards,
>>>>>> Pradip Parkale
>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Thanks & Regards,
>>>>> Pradip Parkale
>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>
>>>>
>>>>
>>>> --
>>>> Thanks & Regards,
>>>> Pradip Parkale
>>>> Software Engineer | EnterpriseDB Corporation
>>>>
>>>
>>>
>>> --
>>> *Thanks & Regards*
>>> *Akshay Joshi*
>>> *pgAdmin Hacker | Principal Software Architect*
>>> *EDB Postgres <http://edbpostgres.com>*
>>>
>>> *Mobile: +91 976-788-8246*
>>>
>>
>>
>> --
>> Thanks & Regards,
>> Pradip Parkale
>> Software Engineer | EnterpriseDB Corporation
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
> *pgAdmin Hacker | Principal Software Architect*
> *EDB Postgres <http://edbpostgres.com>*
>
> *Mobile: +91 976-788-8246*
>


-- 
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

  [application/octet-stream] RM7132_v8.patch (27.5K, 4-RM7132_v8.patch)
  download | inline diff:
diff --git a/web/package.json b/web/package.json
index 2379e9188..d708b05e4 100644
--- a/web/package.json
+++ b/web/package.json
@@ -82,11 +82,6 @@
     "@date-io/core": "^1.3.6",
     "@date-io/date-fns": "1.x",
     "@emotion/sheet": "^1.0.1",
-    "@fortawesome/fontawesome-free": "^5.14.0",
-    "@fortawesome/fontawesome-svg-core": "^6.1.0",
-    "@fortawesome/free-regular-svg-icons": "^6.1.0",
-    "@fortawesome/free-solid-svg-icons": "^6.1.0",
-    "@fortawesome/react-fontawesome": "^0.1.18",
     "@material-ui/core": "4.11.0",
     "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "4.0.0-alpha.58",
@@ -128,7 +123,6 @@
     "date-fns": "^2.24.0",
     "diff-arrays-of-objects": "^1.1.8",
     "dropzone": "^5.9.3",
-    "html-loader": "^3.1.0",
     "html2canvas": "^1.0.0-rc.7",
     "immutability-helper": "^3.0.0",
     "imports-loader": "^2.0.0",
@@ -162,7 +156,6 @@
     "react-dom": "^17.0.1",
     "react-draggable": "^4.4.4",
     "react-rnd": "^10.3.5",
-    "react-fontawesome": "^1.7.1",
     "react-router-dom": "^6.2.2",
     "react-select": "^4.2.1",
     "react-table": "^7.6.3",
diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
index 82001e107..167575d2c 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
@@ -8,7 +8,7 @@
 //////////////////////////////////////////////////////////////
 
 
-import { getNodeAjaxOptions,getNodeListByName } from '../../../../../../static/js/node_ajax';
+import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../static/js/node_ajax';
 import ExtensionsSchema from './extension.ui';
 
 define('pgadmin.node.extension', [
@@ -98,7 +98,8 @@ define('pgadmin.node.extension', [
       getSchema: (treeNodeInfo, itemNodeData)=>{
         let nodeObj = pgAdmin.Browser.Nodes['extension'];
         return new ExtensionsSchema(
-          {
+          {            
+            role:()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
             extensionsList:()=>getNodeAjaxOptions('avails', nodeObj, treeNodeInfo, itemNodeData, { cacheLevel: 'server'},
               (data)=>{
                 let res = [];
diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.ui.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.ui.js
index 918faee7f..b0fcc6bd3 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.ui.js
@@ -24,11 +24,13 @@ export default class ExtensionsSchema extends BaseUISchema {
     });
     fieldOptions = {
       extensionsList: [],
+      role:[],
       schemaList: [],
       ...fieldOptions,
     };
     this.extensionsList = fieldOptions.extensionsList;
     this.schemaList = fieldOptions.schemaList;
+    this.role = fieldOptions.role;
   }
 
   get idAttribute() {
@@ -89,6 +91,12 @@ export default class ExtensionsSchema extends BaseUISchema {
         id: 'oid', label: gettext('OID'), type: 'text',
         mode: ['properties'],
       },
+      {
+        id: 'owner', label: gettext('Owner'),
+        options: this.role,
+        type: 'select',
+        mode: ['properties'], controlProps: { allowClear: false},
+      },
       {
         id: 'schema', label: gettext('Schema'), type: 'select',
         mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
index 3a2bb65a8..576220638 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/operators/static/js/operator.js
@@ -24,6 +24,7 @@ define('pgadmin.node.operator', [
         columns: ['name', 'owner', 'description'],
         canDrop: false,
         canDropCascade: false,
+        canSelect: false
       });
   }
 
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
index b360c6b8d..93944e3b9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js
@@ -29,7 +29,7 @@ function(
         label: gettext('Partitions'),
         type: 'coll-partition',
         columns: [
-          'name', 'schema', 'partition_value', 'is_partitioned', 'description',
+          'name', 'schema', 'partition_scheme',  'partition_value', 'is_partitioned', 'description',
         ],
         canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
         canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js
index 240665432..78760632d 100644
--- a/web/pgadmin/browser/static/js/collection.js
+++ b/web/pgadmin/browser/static/js/collection.js
@@ -6,9 +6,6 @@
 // This software is released under the PostgreSQL Licence
 //
 //////////////////////////////////////////////////////////////
-
-// import {removeNodeView} from './node_view';
-// import Notify from '../../../static/js/helpers/Notifier';
 import {getPanelView} from './panel_view';
 
 define([
@@ -92,11 +89,10 @@ define([
       canDropCascade: true,
       selectParentNodeOnDelete: false,
       showProperties: function(item, data, panel) {
-
-        let container =  panel.$container[0];
+        let container =  panel.$container.find('.obj_properties').first();
         getPanelView(
           pgBrowser.tree,
-          container,
+          container[0],
           pgBrowser,
           panel._type
         );
diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index 21ae4c06d..9e5244b7b 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -1261,16 +1261,11 @@ define('pgadmin.browser.node', [
           $(this).data('node-prop', treeHierarchy);
 
           /* Remove any dom rendered by getNodeView */
-          removeNodeView(pgBrowser.panels['properties'].panel.$container[0]);
-
-          var containerProperties =  pgBrowser.panels['properties'].panel.$container;
-          containerProperties.addClass('pg-panel-content pg-no-overflow pg-el-container');
-
-
+          removeNodeView(j[0]);
           if(that.getSchema) {
             let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item);
             getNodeView(
-              that.type, treeNodeInfo, 'properties', data, 'tab', containerProperties[0], this, onEdit
+              that.type, treeNodeInfo, 'properties', data, 'tab', j[0], this, onEdit
             );
             return;
           }
diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js
index c0bd9178f..cb30580a9 100644
--- a/web/pgadmin/browser/static/js/panel.js
+++ b/web/pgadmin/browser/static/js/panel.js
@@ -122,8 +122,6 @@ define(
                 that.resizedContainer.apply(myPanel);
               }
 
-
-
               if (myPanel._type == 'dashboard') {
                 getPanelView(
                   pgBrowser.tree,
@@ -150,7 +148,7 @@ define(
 
               pgBrowser.Events.on('pgadmin-browser:tree:selected', () => {
 
-                if(myPanel.isVisible()) {
+                if(myPanel.isVisible() && myPanel._type !== 'properties') {
                   getPanelView(
                     pgBrowser.tree,
                     $container[0],
@@ -162,7 +160,7 @@ define(
 
               pgBrowser.Events.on('pgadmin-browser:tree:refreshing', () => {
 
-                if(myPanel.isVisible()) {
+                if(myPanel.isVisible() && myPanel._type !== 'properties') {
                   getPanelView(
                     pgBrowser.tree,
                     $container[0],
@@ -177,7 +175,6 @@ define(
       },
       eventFunc: function(eventName) {
         var name = $(this).data('pgAdminName');
-
         try {
           pgBrowser.Events.trigger(
             'pgadmin-browser:panel', eventName, this, arguments
@@ -244,10 +241,11 @@ define(
           .scene()
           .find('.pg-panel-content');
 
-        if (isPanelVisible) {
+        if (isPanelVisible && selectedPanel._type !== 'properties') {
           if (eventName == 'panelClosed') {
             removePanelView($container[0]);
-          } else if (eventName == 'panelVisibilityChanged') {
+          } 
+          else if (eventName == 'panelVisibilityChanged' && selectedPanel._type !== 'properties') {
             getPanelView(
               pgBrowser.tree,
               $container[0],
diff --git a/web/pgadmin/browser/static/js/panel_view.jsx b/web/pgadmin/browser/static/js/panel_view.jsx
index 39122755d..f212debbf 100644
--- a/web/pgadmin/browser/static/js/panel_view.jsx
+++ b/web/pgadmin/browser/static/js/panel_view.jsx
@@ -53,8 +53,6 @@ export function getPanelView(
       container
     );
   }
-
-
   if (panelType == 'statistics') {
     ReactDOM.render(
       <Theme>
@@ -69,7 +67,7 @@ export function getPanelView(
       container
     );
   }
-  if (panelType == 'properties') {
+  if (panelType == 'properties' && nodeData?.is_collection) {
     ReactDOM.render(
       <Theme>
         <CollectionNodeView
diff --git a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
index 69080e47d..a1450df7b 100644
--- a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
+++ b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
@@ -17,7 +17,7 @@ export default class ActiveQuery extends BaseUISchema {
     });
 
   }
-  
+
   get baseFields() {
     return [
 
@@ -26,7 +26,7 @@ export default class ActiveQuery extends BaseUISchema {
         label: gettext('Backend type'),
         type: 'text',
         editable: true,
-        noEmpty: true,
+        noEmpty: false,
         readonly: true,
         mode: ['properties'],
         group: gettext('Details'),
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
index 9c008b3cb..637f6cde4 100644
--- a/web/pgadmin/dashboard/static/js/Dashboard.jsx
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -25,6 +25,7 @@ import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined
 import WelcomeDashboard from './WelcomeDashboard';
 import ActiveQuery from './ActiveQuery.ui';
 import _ from 'lodash';
+import CachedIcon from '@mui/icons-material/Cached';
 
 function parseData(data) {
   var res = [];
@@ -86,13 +87,25 @@ const useStyles = makeStyles((theme) => ({
     ...theme.mixins.panelBorder,
     flexDirection: 'column',
     overflow: 'hidden !important',
-    flexGrow: 1
+    flexGrow: 1,
+    minWidth: '300px',
+    minHeight: '300px'
+  },
+  arrowButton: {
+    fontSize: '2rem !important',
+    margin: '-7px'
   },
   terminateButton: {
     color: theme.palette.error.main
   },
   buttonClick: {
     backgroundColor: theme.palette.grey[400]
+  },
+  refreshButton: {
+    marginLeft: 'auto',
+    height:  '1.9rem',
+    width:  '2.2rem',
+    ...theme.mixins.panelBorder,
   }
 }));
 
@@ -114,6 +127,7 @@ export default function Dashboard({
   const [msg, setMsg] = useState('');
   const[infoMsg, setInfo] = useState('');
   const [val, setVal] = useState(0);
+  const [refresh, setRefresh] = useState();
   const [schemaDict, setSchemaDict] = React.useState({});
 
   if (!did) {
@@ -145,7 +159,7 @@ export default function Dashboard({
     },
     {
       accessor: 'setting',
-      Header: gettext('Setting'),
+      Header: gettext('Value'),
       sortble: true,
       resizable: true,
       disableGlobalFilter: false,
@@ -273,7 +287,7 @@ export default function Dashboard({
           <PgIconButton
             size="xs"
             noBorder
-            icon={<SquareIcon fontSize="small" />}
+            icon={<SquareIcon/>}
             onClick={() => {
               if (!canTakeAction(row, 'cancel'))
                 return;
@@ -328,12 +342,11 @@ export default function Dashboard({
             className={row.isExpanded ?classes.buttonClick : ''}
             icon={
               row.isExpanded ? (
-                <ArrowDropDownOutlinedIcon  />
+                <ArrowDropDownOutlinedIcon  className={classes.arrowButton}/>
               ) : (
-                <ArrowRightOutlinedIcon />
+                <ArrowRightOutlinedIcon className={classes.arrowButton}/>
               )
             }
-            size="xs"
             noBorder
             onClick={(e) => {
               e.preventDefault();
@@ -753,7 +766,28 @@ export default function Dashboard({
     if (message != '') {
       setMsg(message);
     }
-  }, [nodeData, val, did, preferences, infoMsg]);
+    return () => {
+      setRefresh();
+    };
+  }, [nodeData, val, did, preferences, infoMsg, refresh]);
+
+  const RefreshButton = () =>{
+    return(
+      <PgIconButton
+        size="xs"
+        noBorder
+        className={classes.refreshButton}
+        icon={<CachedIcon />}
+        onClick={(e) => {
+          e.preventDefault();
+          setRefresh(true);
+        }}
+        color="default"
+        aria-label="Refresh"
+        title={gettext('Refresh')}
+      ></PgIconButton>
+    );
+  };
 
   return (
     <>
@@ -783,6 +817,7 @@ export default function Dashboard({
                 {tab.map((tabValue, i) => {
                   return <Tab key={i} label={tabValue} />;
                 })}
+                <RefreshButton/>
               </Tabs>
 
               <PgTable
diff --git a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
index ccb605d67..b2aec80a7 100644
--- a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
+++ b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
@@ -142,6 +142,7 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
     }
     if (message != '') {
       setMsg(message);
+      setLoaderText('');
     }
     return () => {
       setTableData([]);
diff --git a/web/pgadmin/misc/dependents/static/js/Dependents.jsx b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
index 867368b97..6b66e1c50 100644
--- a/web/pgadmin/misc/dependents/static/js/Dependents.jsx
+++ b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
@@ -141,13 +141,14 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       }
     }
     if (message != '') {
+      setLoaderText('');
       setMsg(message);
     }
 
     return () => {
       setTableData([]);
     };
-  }, [nodeData]);
+  }, [nodeData, item]);
 
   return (
     <>
@@ -162,7 +163,6 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       ) : (
         <div className={classes.emptyPanel}>
           {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
-
             <div className={classes.panelIcon}>
               <i className="fa fa-exclamation-circle"></i>
               <span className={classes.panelMessage}>{gettext(msg)}</span>
diff --git a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
index db20331a9..e8a042b36 100644
--- a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
+++ b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
@@ -19,6 +19,8 @@ import PgTable from 'sources/components/PgTable';
 import Theme from 'sources/Theme';
 import PropTypes from 'prop-types';
 import { PgIconButton } from '../../static/js/components/Buttons';
+import DeleteIcon from '@material-ui/icons/Delete';
+import DeleteSweepIcon from '@material-ui/icons/DeleteSweep';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
@@ -155,24 +157,13 @@ export function CollectionNodeView({
         .then(function (res) {
           if (res.success == 0) {
             pgBrowser.report_error(res.errormsg, res.info);
-          } else {
-            pgBrowser.Events.trigger(
-              'pgadmin:browser:tree:refresh',
-              selItem || pgBrowser.tree.selected(),
-              {
-                success: function () {
-                  pgBrowser.tree.select(selItem);
-                  selNode.callbacks.selected.apply(selNode, [selItem]);
-                },
-              }
-            );
           }
           setReload(true);
         })
         .catch(function (error) {
-          Notify.error(
+          Notify.alert(
             gettext('Error dropping %s', selectedItemData._label.toLowerCase()),
-            error.message
+            error.response.data.errormsg
           );
         });
     };
@@ -190,7 +181,6 @@ export function CollectionNodeView({
       let nodeObj =
       pgAdmin.Browser.Nodes[itemNodeData?._type.replace('coll-', '')];
 
-      let schema = nodeObj.getSchema.call(nodeObj, treeNodeInfo, itemNodeData);
       let url = generateCollectionURL.call(nodeObj, item, 'properties');
 
       const api = getApiInstance();
@@ -198,7 +188,8 @@ export function CollectionNodeView({
       let tableColumns = [];
       var column = {};
 
-      if (itemNodeData._type.indexOf('coll-') > -1) {
+      if (itemNodeData._type.indexOf('coll-') > -1 && !_.isUndefined(nodeObj.getSchema)) {
+        let schema = nodeObj.getSchema?.call(nodeObj, treeNodeInfo, itemNodeData);
         schema.fields.forEach((field) => {
           if (node.columns.indexOf(field.id) > -1) {
             if (field.label.indexOf('?') > -1) {
@@ -208,6 +199,7 @@ export function CollectionNodeView({
                 sortble: true,
                 resizable: false,
                 disableGlobalFilter: false,
+                minWidth: 100,
                 // eslint-disable-next-line react/display-name
                 Cell: ({ value }) => {
                   return (<Switch color="primary" checked={value} className={classes.readOnlySwitch} value={value} readOnly title={String(value)} />);
@@ -220,30 +212,45 @@ export function CollectionNodeView({
                 sortble: true,
                 resizable: false,
                 disableGlobalFilter: false,
+                minWidth: 100,
               };
             }
             tableColumns.push(column);
           }
         });
-        api({
-          url: url,
-          type: 'GET',
-        })
-          .then((res) => {
-            res.data.forEach((element) => {
-              element['icon'] = '';
-            });
-            setPgTableColumns(tableColumns);
-            setData(res.data);
-            setInfoMsg('No properties are available for the selected object.');
-          })
-          .catch((err) => {
-            Notify.alert(
-              gettext('Failed to retrieve data from the server.'),
-              gettext(err.message)
-            );
-          });
+      }else{
+        node.columns.forEach((field) => {
+          column = {
+            Header: field,
+            accessor: field,
+            sortble: true,
+            resizable: false,
+            disableGlobalFilter: false,
+            minWidth: 100,
+          };
+          tableColumns.push(column);
+
+        });
       }
+
+      api({
+        url: url,
+        type: 'GET',
+      })
+        .then((res) => {
+          res.data.forEach((element) => {
+            element['icon'] = '';
+          });
+          setPgTableColumns(tableColumns);
+          setData(res.data);
+          setInfoMsg('No properties are available for the selected object.');
+        })
+        .catch((err) => {
+          Notify.alert(
+            gettext('Failed to retrieve data from the server.'),
+            gettext(err.message)
+          );
+        });
     }
   }, [itemNodeData, node, item, reload]);
 
@@ -252,8 +259,8 @@ export function CollectionNodeView({
       <Box >
         <PgIconButton
           className={classes.dropButton}
-          variant="outlined"
-          icon={<i className='fa fa-trash-alt delete_multiple' aria-hidden="true" role="img"></i>}
+
+          icon={<DeleteIcon/>}
           aria-label="Delete/Drop"
           title={gettext('Delete/Drop')}
           onClick={() => {
@@ -267,8 +274,7 @@ export function CollectionNodeView({
         ></PgIconButton>
         <PgIconButton
           className={classes.dropButton}
-          variant="outlined"
-          icon={<i className='pg-font-icon icon-drop_cascade delete_multiple_cascade' aria-hidden="true" role="img"></i>}
+          icon={<DeleteSweepIcon />}
           aria-label="Drop Cascade"
           title={gettext('Drop Cascade')}
           onClick={() => {
@@ -284,12 +290,12 @@ export function CollectionNodeView({
   };
 
   return (
-    <Theme>
+    <Theme className='obj_properties'>
       <Box className={classes.propertiesPanel}>
         {data.length > 0 ?
           (
             <PgTable
-              isSelectRow={!('catalog' in treeNodeInfo) && (itemNodeData.label !== 'Catalogs')}
+              isSelectRow={!('catalog' in treeNodeInfo) && (itemNodeData.label !== 'Catalogs') && _.isUndefined(node?.canSelect)}
               customHeader={customHeader}
               className={classes.autoResizer}
               columns={pgTableColumns}
diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
index 305262680..c567b1e8d 100644
--- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx
+++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
@@ -206,6 +206,7 @@ export default function Statistics({ nodeData, item, node, ...props }) {
     }
     if (message != '') {
       setMsg(message);
+      setLoaderText('');
     }
     return () => {
       setTableData([]);
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index b6f9d12cb..265d833f3 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -47,7 +47,7 @@ const useStyles = makeStyles((theme) => ({
     overflow: 'overlay !important',
   },
   customHeader:{
-    marginTop: '12px',
+    marginTop: '8px',
     marginLeft: '4px'
   },
   searchBox: {
@@ -55,6 +55,13 @@ const useStyles = makeStyles((theme) => ({
     display: 'flex',
     background: theme.palette.background.default
   },
+  warning: {
+    backgroundColor: theme.palette.warning.main + '!important'
+  },
+  alert: {
+    backgroundColor: theme.palette.error.main + '!important'
+  },
+
   tableContentWidth: {
     width: 'calc(100% - 3px)',
   },
@@ -105,10 +112,11 @@ const useStyles = makeStyles((theme) => ({
     textOverflow: 'ellipsis',
     whiteSpace: 'nowrap',
     backgroundColor: theme.otherVars.tableBg,
+    userSelect: 'text'
   },
   selectCell: {
     textAlign: 'center',
-    minWidth: '25px'
+    minWidth: 20
   },
   tableCellHeader: {
     fontWeight: theme.typography.fontWeightBold,
@@ -177,6 +185,10 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
   const rowHeights = React.useRef({});
   const rowRef = React.useRef({});
 
+  // Reset Search vakue in tab changed.
+  React.useEffect(()=>{
+    setSearchVal('');
+  },[columns]);
   function getRowHeight(index, size) {
     return rowHeights.current[index] + size || 35;
   }
@@ -257,21 +269,49 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
               id: 'selection',
               // The header can use the table's getToggleAllRowsSelectedProps method
               // to render a checkbox
-              Header: ({ getToggleAllRowsSelectedProps }) => (
-                <div className={classes.selectCell}>
-                  <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
-                </div>
-              ),
+              Header: ({ getToggleAllRowsSelectedProps, toggleRowSelected, isAllRowsSelected, rows }) => {
+
+                const modifiedOnChange = (event) => {
+                  rows.forEach((row) => {
+                    //check each row if it is not disabled
+                    !(!_.isUndefined(row.original.canDrop) && !(row.original.canDrop)) && toggleRowSelected(row.id, event.currentTarget.checked);
+
+                  });
+                };
+
+                let allTableRows = 0;
+                let selectedTableRows = 0;
+                rows.forEach((row) => {
+                  row.isSelected && selectedTableRows++;
+                  (_.isUndefined(row.original.canDrop) || row.original.canDrop) && allTableRows++;
+                });
+                const disabled = allTableRows === 0;
+                const checked =
+                    (isAllRowsSelected ||
+                      allTableRows === selectedTableRows) &&
+                    !disabled;
+                return(
+                  <div className={classes.selectCell}>
+                    <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()
+                    }
+                    onChange={modifiedOnChange}
+                    checked={checked}
+                    />
+                  </div>
+                );},
               // The cell can use the individual row's getToggleRowSelectedProps method
               // to the render a checkbox
               Cell: ({ row }) => (
                 <div className={classes.selectCell}>
-                  <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
+                  <IndeterminateCheckbox {...row.getToggleRowSelectedProps()}
+                    disabled={!_.isUndefined(row.original.canDrop) ? !(row.original.canDrop) : false}
+                  />
                 </div>
               ),
               sortble: false,
               width: 30,
-              minWidth: 0,
+              maxWidth: 30,
+              minWidth: 0
             },
             ...CLOUMNS,
           ];
@@ -337,8 +377,15 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
               if(cell.column.id == 'btn-edit' && row.isExpanded) {
                 classNames.push(classes.expandedIconCell);
               }
+              if (row.original.row_type === 'warning'){
+                classNames.push(classes.warning);
+              }
+              if (row.original.row_type === 'alert'){
+                classNames.push(classes.alert);
+              }
               return (
-                <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classNames, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)} title={String(cell.value)}>
+                <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classNames, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)}
+                  title={_.isUndefined(cell.value) || _.isNull(cell.value) ? '': String(cell.value)}>
                   {cell.render('Cell')}
                 </div>
               );
@@ -467,14 +514,17 @@ PgTable.propTypes = {
     PropTypes.node,
   ]),
   getToggleAllRowsSelectedProps: PropTypes.func,
+  toggleRowSelected: PropTypes.func,
   columns: PropTypes.array,
   data: PropTypes.array,
   isSelectRow: PropTypes.bool,
+  isAllRowsSelected: PropTypes.bool,
   row: PropTypes.func,
   setSelectedRows: PropTypes.func,
   getSelectedRows: PropTypes.func,
   searchText: PropTypes.string,
   type: PropTypes.string,
   sortOptions: PropTypes.array,
-  schema: PropTypes.object
+  schema: PropTypes.object,
+  rows: PropTypes.object
 };


^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-28 06:28       ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-30 06:00         ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-30 06:38           ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-04-04 12:05             ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
@ 2022-04-04 12:14               ` Akshay Joshi <[email protected]>
  2022-04-05 07:32                 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Akshay Joshi @ 2022-04-04 12:14 UTC (permalink / raw)
  To: Pradip Parkale <[email protected]>; +Cc: Aditya Toshniwal <[email protected]>; pgadmin-hackers

Thanks, the patch applied.

On Mon, Apr 4, 2022 at 5:35 PM Pradip Parkale <
[email protected]> wrote:

> Hi Akshay,
> Please find an updated patch. I have fixed the issue found in the testing.
>
> On Wed, Mar 30, 2022 at 12:08 PM Akshay Joshi <
> [email protected]> wrote:
>
>> Thanks, the patch applied.
>>
>> On Wed, Mar 30, 2022 at 11:31 AM Pradip Parkale <
>> [email protected]> wrote:
>>
>>> Hi Akhay,
>>>
>>> Please find the updated patch.I have fixed all the issues.
>>>
>>> On Mon, Mar 28, 2022 at 11:58 AM Akshay Joshi <
>>> [email protected]> wrote:
>>>
>>>> Hi Pradip
>>>>
>>>> Following are the review comments (GUI):
>>>>
>>>>    - Catalog objects should not be drop or drop cascade. Remove
>>>>    checkboxes from the properties panel.
>>>>    -  Database column should be there for the 'Server Activity' table
>>>>    all tabs when the server is selected. When the database is selected it
>>>>    should be hidden.
>>>>    - Rename 'Lock' tab to 'Locks'.
>>>>    - Remove extra column 'Waiting' which was not there originally.
>>>>    - 'Server Activity' -> Sessions-> Details for the last record is
>>>>    not readable. Fix the scroll bar issue. Same with the Configuration tab
>>>>    last 4-5 records are not readable.
>>>>    -  Select and expand the first and second records, the rest of the
>>>>    records are not visible, again seems to be a scroll bar issue.
>>>>    - 'Server Activity' -> Locks, "Granted?" column is empty, not
>>>>    showing any value.
>>>>    - Set the width of the column appropriately for all the tabs, for
>>>>    example, unit columns (in Configuration tab) width should be less, so that
>>>>    data on the other columns are more readable. Check all the tabs and set
>>>>    them appropriately
>>>>    - Faced "Request failed with status code 404" error. Select
>>>>    database server from browser tree and then select 'Server Activity'
>>>>    -> Configuration. Now select any database, you will get the error.
>>>>    - Properties panel size of the column having checkboxes should be
>>>>    less, compare with existing behavior.
>>>>    - Properties panel should show the message '*No Properties are
>>>>    available for the selected object*' if the respective collection
>>>>    node does not have children.
>>>>
>>>>
>>>>
>>>> On Mon, Mar 28, 2022 at 10:08 AM Pradip Parkale <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi,
>>>>> Here is the updated patch. This patch includes the fix for #7215
>>>>> <https://redmine.postgresql.org/issues/7215;.
>>>>>
>>>>> On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Aditya,
>>>>>> Please ignore the previous email, find the updated patch attached.
>>>>>>
>>>>>> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Aditya,
>>>>>>> Please find the updated patch.
>>>>>>>
>>>>>>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Pradip,
>>>>>>>>
>>>>>>>> I did some basic usage and review and found below issues:
>>>>>>>> 1. The code fails if you refresh the page and go to properties,
>>>>>>>> when no node is selected.
>>>>>>>> 2. I found below UI issues on selecting a database node. Also,
>>>>>>>> checkbox column is too wide.
>>>>>>>> [image: image.png]
>>>>>>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>>>>>>
>>>>>>>> +
>>>>>>>>
>>>>>>>> +              ReactDOM.render(
>>>>>>>>
>>>>>>>> +                <Theme>
>>>>>>>>
>>>>>>>> +                  <CollectionNodeView
>>>>>>>>
>>>>>>>> +                    node={node}
>>>>>>>>
>>>>>>>> +                    treeNodeInfo={treeNodeInfo}
>>>>>>>>
>>>>>>>> +                    item={item}
>>>>>>>>
>>>>>>>> +                    itemNodeData={d}
>>>>>>>>
>>>>>>>> +                    pgBrowser={pgBrowser}
>>>>>>>>
>>>>>>>> +                  ></CollectionNodeView>
>>>>>>>>
>>>>>>>> +                </Theme>,
>>>>>>>>
>>>>>>>> +                b.panels['properties'].panel.$container[0]
>>>>>>>>
>>>>>>>> +              );
>>>>>>>>
>>>>>>>> 4. I have seen a lot of commented codes. Few samples:
>>>>>>>>
>>>>>>>> +              // if (that.canHide) {
>>>>>>>>
>>>>>>>>
>>>>>>>> +              //
>>>>>>>> pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
>>>>>>>>
>>>>>>>> +
>>>>>>>>
>>>>>>>> +              //     removePanelView($container[0]);
>>>>>>>>
>>>>>>>> +              // });
>>>>>>>>
>>>>>>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please
>>>>>>>> move it to a file and import it.
>>>>>>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>>>>>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>>>>>>> 8. Rename Sql.jsx to SQL.jsx
>>>>>>>> 9. The search is not working. It filters all.
>>>>>>>> 10. If there is huge data then it should show some spinner.
>>>>>>>> 11. Delete buttons should be disabled if no object is selected.
>>>>>>>> 12. Delete buttons and search box should be on the same line.
>>>>>>>>
>>>>>>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Aditya
>>>>>>>>>
>>>>>>>>> Can you please review/test it?
>>>>>>>>>
>>>>>>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Hackers,
>>>>>>>>>>
>>>>>>>>>> Please find the attached patch for #7132
>>>>>>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>>>>>>> collection, Dashboard and SQL panel in React.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Thanks & Regards,
>>>>>>>>>> Pradip Parkale
>>>>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> *Thanks & Regards*
>>>>>>>>> *Akshay Joshi*
>>>>>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>>>>>
>>>>>>>>> *Mobile: +91 976-788-8246*
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Thanks,
>>>>>>>> Aditya Toshniwal
>>>>>>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>>>>>>> <http://edbpostgres.com;
>>>>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Thanks & Regards,
>>>>>>> Pradip Parkale
>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Thanks & Regards,
>>>>>> Pradip Parkale
>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Thanks & Regards,
>>>>> Pradip Parkale
>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>
>>>>
>>>>
>>>> --
>>>> *Thanks & Regards*
>>>> *Akshay Joshi*
>>>> *pgAdmin Hacker | Principal Software Architect*
>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>
>>>> *Mobile: +91 976-788-8246*
>>>>
>>>
>>>
>>> --
>>> Thanks & Regards,
>>> Pradip Parkale
>>> Software Engineer | EnterpriseDB Corporation
>>>
>>
>>
>> --
>> *Thanks & Regards*
>> *Akshay Joshi*
>> *pgAdmin Hacker | Principal Software Architect*
>> *EDB Postgres <http://edbpostgres.com>*
>>
>> *Mobile: +91 976-788-8246*
>>
>
>
> --
> Thanks & Regards,
> Pradip Parkale
> Software Engineer | EnterpriseDB Corporation
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React
  2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-15 10:31 ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-15 12:09   ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Aditya Toshniwal <[email protected]>
  2022-03-28 04:37     ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-28 06:28       ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-03-30 06:00         ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-03-30 06:38           ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
  2022-04-04 12:05             ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
  2022-04-04 12:14               ` Re: [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Akshay Joshi <[email protected]>
@ 2022-04-05 07:32                 ` Pradip Parkale <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Pradip Parkale @ 2022-04-05 07:32 UTC (permalink / raw)
  To: Akshay Joshi <[email protected]>; +Cc: Aditya Toshniwal <[email protected]>; pgadmin-hackers

Hi Akshay,

Please find the updated patch.

On Mon, Apr 4, 2022 at 5:44 PM Akshay Joshi <[email protected]>
wrote:

> Thanks, the patch applied.
>
> On Mon, Apr 4, 2022 at 5:35 PM Pradip Parkale <
> [email protected]> wrote:
>
>> Hi Akshay,
>> Please find an updated patch. I have fixed the issue found in the testing.
>>
>> On Wed, Mar 30, 2022 at 12:08 PM Akshay Joshi <
>> [email protected]> wrote:
>>
>>> Thanks, the patch applied.
>>>
>>> On Wed, Mar 30, 2022 at 11:31 AM Pradip Parkale <
>>> [email protected]> wrote:
>>>
>>>> Hi Akhay,
>>>>
>>>> Please find the updated patch.I have fixed all the issues.
>>>>
>>>> On Mon, Mar 28, 2022 at 11:58 AM Akshay Joshi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Pradip
>>>>>
>>>>> Following are the review comments (GUI):
>>>>>
>>>>>    - Catalog objects should not be drop or drop cascade. Remove
>>>>>    checkboxes from the properties panel.
>>>>>    -  Database column should be there for the 'Server Activity' table
>>>>>    all tabs when the server is selected. When the database is selected it
>>>>>    should be hidden.
>>>>>    - Rename 'Lock' tab to 'Locks'.
>>>>>    - Remove extra column 'Waiting' which was not there originally.
>>>>>    - 'Server Activity' -> Sessions-> Details for the last record is
>>>>>    not readable. Fix the scroll bar issue. Same with the Configuration tab
>>>>>    last 4-5 records are not readable.
>>>>>    -  Select and expand the first and second records, the rest of the
>>>>>    records are not visible, again seems to be a scroll bar issue.
>>>>>    - 'Server Activity' -> Locks, "Granted?" column is empty, not
>>>>>    showing any value.
>>>>>    - Set the width of the column appropriately for all the tabs, for
>>>>>    example, unit columns (in Configuration tab) width should be less, so that
>>>>>    data on the other columns are more readable. Check all the tabs and set
>>>>>    them appropriately
>>>>>    - Faced "Request failed with status code 404" error. Select
>>>>>    database server from browser tree and then select 'Server Activity'
>>>>>    -> Configuration. Now select any database, you will get the error.
>>>>>    - Properties panel size of the column having checkboxes should be
>>>>>    less, compare with existing behavior.
>>>>>    - Properties panel should show the message '*No Properties are
>>>>>    available for the selected object*' if the respective collection
>>>>>    node does not have children.
>>>>>
>>>>>
>>>>>
>>>>> On Mon, Mar 28, 2022 at 10:08 AM Pradip Parkale <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi,
>>>>>> Here is the updated patch. This patch includes the fix for #7215
>>>>>> <https://redmine.postgresql.org/issues/7215;.
>>>>>>
>>>>>> On Mon, Mar 28, 2022 at 9:11 AM Pradip Parkale <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hi Aditya,
>>>>>>> Please ignore the previous email, find the updated patch attached.
>>>>>>>
>>>>>>> On Sun, Mar 27, 2022 at 11:07 PM Pradip Parkale <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Aditya,
>>>>>>>> Please find the updated patch.
>>>>>>>>
>>>>>>>> On Tue, Mar 15, 2022 at 5:40 PM Aditya Toshniwal <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Pradip,
>>>>>>>>>
>>>>>>>>> I did some basic usage and review and found below issues:
>>>>>>>>> 1. The code fails if you refresh the page and go to properties,
>>>>>>>>> when no node is selected.
>>>>>>>>> 2. I found below UI issues on selecting a database node. Also,
>>>>>>>>> checkbox column is too wide.
>>>>>>>>> [image: image.png]
>>>>>>>>> 3. Why is this in the node.js file. It should be in node_view.jsx.
>>>>>>>>>
>>>>>>>>> +
>>>>>>>>>
>>>>>>>>> +              ReactDOM.render(
>>>>>>>>>
>>>>>>>>> +                <Theme>
>>>>>>>>>
>>>>>>>>> +                  <CollectionNodeView
>>>>>>>>>
>>>>>>>>> +                    node={node}
>>>>>>>>>
>>>>>>>>> +                    treeNodeInfo={treeNodeInfo}
>>>>>>>>>
>>>>>>>>> +                    item={item}
>>>>>>>>>
>>>>>>>>> +                    itemNodeData={d}
>>>>>>>>>
>>>>>>>>> +                    pgBrowser={pgBrowser}
>>>>>>>>>
>>>>>>>>> +                  ></CollectionNodeView>
>>>>>>>>>
>>>>>>>>> +                </Theme>,
>>>>>>>>>
>>>>>>>>> +                b.panels['properties'].panel.$container[0]
>>>>>>>>>
>>>>>>>>> +              );
>>>>>>>>>
>>>>>>>>> 4. I have seen a lot of commented codes. Few samples:
>>>>>>>>>
>>>>>>>>> +              // if (that.canHide) {
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> +              //
>>>>>>>>> pgBrowser.Events.off('pgadmin-browser:tree:selected', () => {
>>>>>>>>>
>>>>>>>>> +
>>>>>>>>>
>>>>>>>>> +              //     removePanelView($container[0]);
>>>>>>>>>
>>>>>>>>> +              // });
>>>>>>>>>
>>>>>>>>> 5. In WelcomeDashboard.jsx, the complete SVG code is put. Please
>>>>>>>>> move it to a file and import it.
>>>>>>>>> 6. Cleanup web/pgadmin/dashboard/static/js/dashboardDummy.js
>>>>>>>>> 7. Cleanup web/pgadmin/dashboard/static/js/dashboard_ponents.jsx
>>>>>>>>> 8. Rename Sql.jsx to SQL.jsx
>>>>>>>>> 9. The search is not working. It filters all.
>>>>>>>>> 10. If there is huge data then it should show some spinner.
>>>>>>>>> 11. Delete buttons should be disabled if no object is selected.
>>>>>>>>> 12. Delete buttons and search box should be on the same line.
>>>>>>>>>
>>>>>>>>> On Tue, Mar 15, 2022 at 4:01 PM Akshay Joshi <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Aditya
>>>>>>>>>>
>>>>>>>>>> Can you please review/test it?
>>>>>>>>>>
>>>>>>>>>> On Mon, Mar 14, 2022 at 7:17 PM Pradip Parkale <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Hackers,
>>>>>>>>>>>
>>>>>>>>>>> Please find the attached patch for #7132
>>>>>>>>>>> <https://redmine.postgresql.org/issues/7132; Port Properties
>>>>>>>>>>> collection, Dashboard and SQL panel in React.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Thanks & Regards,
>>>>>>>>>>> Pradip Parkale
>>>>>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> *Thanks & Regards*
>>>>>>>>>> *Akshay Joshi*
>>>>>>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>>>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>>>>>>
>>>>>>>>>> *Mobile: +91 976-788-8246*
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Thanks,
>>>>>>>>> Aditya Toshniwal
>>>>>>>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>>>>>>>> <http://edbpostgres.com;
>>>>>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Thanks & Regards,
>>>>>>>> Pradip Parkale
>>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Thanks & Regards,
>>>>>>> Pradip Parkale
>>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Thanks & Regards,
>>>>>> Pradip Parkale
>>>>>> Software Engineer | EnterpriseDB Corporation
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> *Thanks & Regards*
>>>>> *Akshay Joshi*
>>>>> *pgAdmin Hacker | Principal Software Architect*
>>>>> *EDB Postgres <http://edbpostgres.com>*
>>>>>
>>>>> *Mobile: +91 976-788-8246*
>>>>>
>>>>
>>>>
>>>> --
>>>> Thanks & Regards,
>>>> Pradip Parkale
>>>> Software Engineer | EnterpriseDB Corporation
>>>>
>>>
>>>
>>> --
>>> *Thanks & Regards*
>>> *Akshay Joshi*
>>> *pgAdmin Hacker | Principal Software Architect*
>>> *EDB Postgres <http://edbpostgres.com>*
>>>
>>> *Mobile: +91 976-788-8246*
>>>
>>
>>
>> --
>> Thanks & Regards,
>> Pradip Parkale
>> Software Engineer | EnterpriseDB Corporation
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
> *pgAdmin Hacker | Principal Software Architect*
> *EDB Postgres <http://edbpostgres.com>*
>
> *Mobile: +91 976-788-8246*
>


-- 
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation


Attachments:

  [image/png] image.png (249.1K, 3-image.png)
  download | view image

  [application/octet-stream] RM7132_v9.patch (9.4K, 4-RM7132_v9.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
index 697ddf265..9af351d31 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
@@ -23,7 +23,7 @@ define('pgadmin.node.publication', [
         node: 'publication',
         label: gettext('Publications'),
         type: 'coll-publication',
-        columns: ['name', 'pubowner', 'proptable', 'all_table'],
+        columns: ['name', 'pubowner', 'pubtable', 'all_table'],
 
       });
   }
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
index 55736d4b0..d338f1339 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.ui.js
@@ -144,11 +144,8 @@ export default class PublicationSchema extends BaseUISchema {
       id: 'pubtable', label: gettext('Tables'), type: 'select',
       controlProps: { allowClear: true, multiple: true, creatable: true },
       options: this.fieldOptions.publicationTable,
-      group: gettext('Definition'), mode: ['edit', 'create'],
+      group: gettext('Definition'), mode: ['edit', 'create', 'properties'],
       deps: ['all_table'], disabled: obj.isAllTable,
-    },{
-      id: 'proptable', label: gettext('Tables'), type: 'text', group: gettext('Definition'),
-      mode: ['properties'],
     },{
       type: 'nested-fieldset', mode: ['create','edit', 'properties'],
       label: gettext('With'), group: gettext('Definition'),
diff --git a/web/pgadmin/browser/static/js/panel.js b/web/pgadmin/browser/static/js/panel.js
index b76a90c1c..ce59e5650 100644
--- a/web/pgadmin/browser/static/js/panel.js
+++ b/web/pgadmin/browser/static/js/panel.js
@@ -147,7 +147,7 @@ define(
                 });
 
               pgBrowser.Events.on('pgadmin-browser:tree:selected', () => {
-
+                
                 if(myPanel.isVisible() && myPanel._type !== 'properties') {
                   getPanelView(
                     pgBrowser.tree,
@@ -158,6 +158,18 @@ define(
                 }
               });
 
+              pgBrowser.Events.on('pgadmin:database:connected', () => {
+
+                if(myPanel.isVisible() && myPanel._type == 'dashboard' && myPanel._type !== 'properties') {
+                  getPanelView(
+                    pgBrowser.tree,
+                    $container[0],
+                    pgBrowser,
+                    myPanel._type
+                  );
+                }
+              });
+
               pgBrowser.Events.on('pgadmin-browser:tree:refreshing', () => {
 
                 if(myPanel.isVisible() && myPanel._type !== 'properties') {
diff --git a/web/pgadmin/browser/static/js/panel_view.jsx b/web/pgadmin/browser/static/js/panel_view.jsx
index f212debbf..e10b2d738 100644
--- a/web/pgadmin/browser/static/js/panel_view.jsx
+++ b/web/pgadmin/browser/static/js/panel_view.jsx
@@ -48,6 +48,7 @@ export function getPanelView(
           did={((!_.isUndefined(treeNodeInfo)) && (!_.isUndefined(treeNodeInfo['database']))) ? treeNodeInfo['database']._id: 0}
           sid={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo['server']._id : ''}
           serverConnected={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['server']) ? treeNodeInfo.server.connected: false}
+          dbConnected={!_.isUndefined(treeNodeInfo) && !_.isUndefined(treeNodeInfo['database']) ? treeNodeInfo.database.connected: false}
         />
       </Theme>,
       container
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
index d2340f63a..4c0d91874 100644
--- a/web/pgadmin/dashboard/static/js/Dashboard.jsx
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -741,6 +741,7 @@ export default function Dashboard({
       }
 
       message = gettext('Loading dashboard...');
+      if (did && !props.dbConnected) return;
       if (did) url += sid + '/' + did;
       else url += sid;
 
@@ -771,7 +772,7 @@ export default function Dashboard({
     return () => {
       setRefresh();
     };
-  }, [nodeData, val, did, preferences, infoMsg, refresh]);
+  }, [nodeData, val, did, preferences, infoMsg, refresh, props.dbConnected]);
 
   const RefreshButton = () =>{
     return(
@@ -874,6 +875,7 @@ Dashboard.propTypes = {
   did: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
   row: PropTypes.object,
   serverConnected: PropTypes.bool,
+  dbConnected: PropTypes.bool,
 };
 
 export function ChartContainer(props) {
diff --git a/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
index ea4b58003..8a75a63f4 100644
--- a/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
+++ b/web/pgadmin/dashboard/static/js/WelcomeDashboard.jsx
@@ -72,7 +72,7 @@ const useStyles = makeStyles((theme) => ({
     cursor: 'pointer'
   },
   link: {
-    color: theme.otherVars.colorFg + '!important',
+    color: theme.otherVars.stepFg + '!important',
   },
   cardColumn: {
     flex: '0 0 100%',
diff --git a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
index 1b8f56730..05aeef26d 100644
--- a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
+++ b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
@@ -86,7 +86,7 @@ export function CollectionNodeView({
   const [data, setData] = React.useState([]);
   const [infoMsg, setInfoMsg] = React.useState('Please select an object in the tree view.');
   const [selectedObject, setSelectedObject] = React.useState([]);
-  const [reload, setReload] = React.useState();
+  const [reload, setReload] = React.useState(false);
 
   const [pgTableColumns, setPgTableColumns] = React.useState([
     {
@@ -162,7 +162,7 @@ export function CollectionNodeView({
           if (res.success == 0) {
             pgBrowser.report_error(res.errormsg, res.info);
           }
-          setReload(true);
+          setReload(!reload);
         })
         .catch(function (error) {
           Notify.alert(
diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
index 50fa4965a..7ed0dc198 100644
--- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx
+++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
@@ -221,7 +221,6 @@ export default function Statistics({ nodeData, item, node, ...props }) {
     }
     if (message != '') {
       setMsg(message);
-      setLoaderText('');
     }
     return () => {
       setTableData([]);
diff --git a/web/pgadmin/static/js/Theme/dark.js b/web/pgadmin/static/js/Theme/dark.js
index 8808262ac..617af6753 100644
--- a/web/pgadmin/static/js/Theme/dark.js
+++ b/web/pgadmin/static/js/Theme/dark.js
@@ -93,7 +93,6 @@ export default function(basicSettings) {
       stepBg: '#FFFFFF',
       stepFg: '#000',
       toggleBtnBg: '#000',
-      colorFg: '#FFFFFF',
       emptySpaceBg: '#212121',
     }
   });
diff --git a/web/pgadmin/static/js/Theme/high_contrast.js b/web/pgadmin/static/js/Theme/high_contrast.js
index 0fb330ae3..c9d0af429 100644
--- a/web/pgadmin/static/js/Theme/high_contrast.js
+++ b/web/pgadmin/static/js/Theme/high_contrast.js
@@ -91,7 +91,6 @@ export default function(basicSettings) {
       stepBg: '#FFFFFF',
       stepFg: '#000',
       toggleBtnBg: '#6B6B6B',
-      colorFg: '#FFFFFF',
       emptySpaceBg: '#010B15',
     }
   });
diff --git a/web/pgadmin/static/js/Theme/standard.js b/web/pgadmin/static/js/Theme/standard.js
index b4e2b88b1..998429f00 100644
--- a/web/pgadmin/static/js/Theme/standard.js
+++ b/web/pgadmin/static/js/Theme/standard.js
@@ -85,7 +85,6 @@ export default function(basicSettings) {
         padding: '5px 8px',
       },
       borderColor: '#dde0e6',
-      colorFg: '#222222',
       loader: {
         backgroundColor: fade('#000', 0.65),
         color: '#fff',
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index 5ea0c0c7e..35ed86488 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -381,23 +381,17 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, ..
   const RenderRow = React.useCallback(
     ({ index, style }) => {
       const row = rows[index];
-      const [expandComplete, setExpandComplete] = React.useState(null);
+      const [expandComplete, setExpandComplete] = React.useState(false);
       const rowRef = React.useRef() ;
       prepareRow(row);
 
-      React.useEffect(()=>{
-        if(expandComplete && !row.isExpanded) {
-          setExpandComplete(false);
-        }
-      }, [row.isExpanded]);
-
       React.useEffect(()=>{
         if(rowRef.current) {
-          if(expandComplete == null) {
+          if(!expandComplete && rowRef.current.style.height == `${ROW_HEIGHT}px`) {
             return;
           }
           let rowHeight;
-          rowRef.current.style.height='unset';
+          rowRef.current.style.height = 'unset';
           if(expandComplete) {
             rowHeight = rowRef.current.offsetHeight;
           } else {


^ permalink  raw  reply  [nested|flat] 10+ messages in thread


end of thread, other threads:[~2022-04-05 07:32 UTC | newest]

Thread overview: 10+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2022-03-14 13:47 [pgAdmin][RM-7132]: Port Properties collection, Dashboard and SQL panel in React Pradip Parkale <[email protected]>
2022-03-15 10:31 ` Akshay Joshi <[email protected]>
2022-03-15 12:09   ` Aditya Toshniwal <[email protected]>
2022-03-28 04:37     ` Pradip Parkale <[email protected]>
2022-03-28 06:28       ` Akshay Joshi <[email protected]>
2022-03-30 06:00         ` Pradip Parkale <[email protected]>
2022-03-30 06:38           ` Akshay Joshi <[email protected]>
2022-04-04 12:05             ` Pradip Parkale <[email protected]>
2022-04-04 12:14               ` Akshay Joshi <[email protected]>
2022-04-05 07:32                 ` Pradip Parkale <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox