You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2014/11/25 18:14:25 UTC

[01/10] ambari git commit: AMBARI-8428. "Service actions" drop down menu is continuously re-created (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 34e0274d1 -> 82e72e517


AMBARI-8428. "Service actions" drop down menu is continuously re-created (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/bf193642
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/bf193642
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/bf193642

Branch: refs/heads/trunk
Commit: bf193642ddb3f83943df6749f7d2bf5acda01f71
Parents: 34e0274
Author: Alex Antonenko <hi...@gmail.com>
Authored: Mon Nov 24 19:53:52 2014 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue Nov 25 19:13:18 2014 +0200

----------------------------------------------------------------------
 ambari-web/app/views/main/service/item.js       |  25 +-
 ambari-web/test/views/main/service/item_test.js | 389 ++++++++++++++++++-
 2 files changed, 392 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/bf193642/ambari-web/app/views/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/item.js b/ambari-web/app/views/main/service/item.js
index ef6fb21..7b3c7a5 100644
--- a/ambari-web/app/views/main/service/item.js
+++ b/ambari-web/app/views/main/service/item.js
@@ -177,7 +177,13 @@ App.MainServiceItemView = Em.View.extend({
     return $.extend(true, {}, option, fields);
   },
 
-  maintenance: function(){
+  maintenance: [],
+
+  observeMaintenance: function() {
+    Em.run.once(this, 'observeMaintenanceOnce');
+  }.observes('controller.isStopDisabled','controller.isClientsOnlyService', 'controller.content.isRestartRequired'),
+
+  observeMaintenanceOnce: function() {
     var self = this;
     var options = [];
     var service = this.get('controller.content');
@@ -287,8 +293,21 @@ App.MainServiceItemView = Em.View.extend({
       options.push(actionMap.DOWNLOAD_CLIENT_CONFIGS);
     }
 
-    return options;
-  }.property('controller.content', 'controller.isStopDisabled','controller.isClientsOnlyService', 'controller.content.isRestartRequired', 'isPassive'),
+    if (!this.get('maintenance').length) {
+      this.set('maintenance', options);
+    } else {
+      this.get('maintenance').forEach(function(option, index) {
+        if ( JSON.stringify(option) != JSON.stringify(options[index])  ) {
+          self.get('maintenance').removeAt(index).insertAt(index, options[index]);
+        }
+      });
+      options.forEach(function(opt, index) {
+        if ( JSON.stringify(opt) != JSON.stringify(self.get('maintenance')[index])  ) {
+          self.get('maintenance').push(opt);
+        }
+      });
+    }
+  },
 
   isMaintenanceActive: function() {
     return this.get('maintenance').length !== 0;

http://git-wip-us.apache.org/repos/asf/ambari/blob/bf193642/ambari-web/test/views/main/service/item_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/service/item_test.js b/ambari-web/test/views/main/service/item_test.js
index 3acc57d..7ffa06e 100644
--- a/ambari-web/test/views/main/service/item_test.js
+++ b/ambari-web/test/views/main/service/item_test.js
@@ -19,28 +19,24 @@
 var App = require('app');
 require('views/main/service/item');
 
-describe('App.MainServiceItemView', function() {
-
-  var view = App.MainServiceItemView.create({
-    controller: Em.Object.create({
-      content:{
-        hostComponents: []
-      }
-    })
-  });
-
-  describe('#mastersExcludedCommands', function() {
+describe('App.MainServiceItemView', function () {
 
-    var nonCustomAction = ['RESTART_ALL', 'RUN_SMOKE_TEST', 'REFRESH_CONFIGS', 'ROLLING_RESTART', 'TOGGLE_PASSIVE', 'TOGGLE_NN_HA', 'TOGGLE_RM_HA', 'MOVE_COMPONENT', 'DOWNLOAD_CLIENT_CONFIGS','MASTER_CUSTOM_COMMAND'];
+  describe('#mastersExcludedCommands', function () {
+    var view = App.MainServiceItemView.create({
+      controller: Em.Object.create({
+        content: Em.Object.create({
+          hostComponents: []
+        })
+      })
+    });
 
+    var nonCustomAction = ['RESTART_ALL', 'RUN_SMOKE_TEST', 'REFRESH_CONFIGS', 'ROLLING_RESTART', 'TOGGLE_PASSIVE', 'TOGGLE_NN_HA', 'TOGGLE_RM_HA', 'MOVE_COMPONENT', 'DOWNLOAD_CLIENT_CONFIGS', 'MASTER_CUSTOM_COMMAND'];
     var keys = Object.keys(view.mastersExcludedCommands);
     var mastersExcludedCommands = [];
     for (var i = 0; i < keys.length; i++) {
       mastersExcludedCommands[i] = view.mastersExcludedCommands[keys[i]];
     }
-    console.log("value of masterExcluded: " + mastersExcludedCommands);
-    var allMastersExcludedCommands = mastersExcludedCommands.reduce(function(previous, current){
-      console.log(previous);
+    var allMastersExcludedCommands = mastersExcludedCommands.reduce(function (previous, current) {
       return previous.concat(current);
     });
     var actionMap = view.actionMap();
@@ -49,18 +45,373 @@ describe('App.MainServiceItemView', function() {
     for (var iter in actionMap) {
       customActionsArray.push(actionMap[iter]);
     }
-    var customActions = customActionsArray.mapProperty('customCommand').filter(function(action){
+    var customActions = customActionsArray.mapProperty('customCommand').filter(function (action) {
       return !nonCustomAction.contains(action);
     }).uniq();
 
     // remove null and undefined from the list
-    customActions = customActions.filter(function(value) { return value != null; });
+    customActions = customActions.filter(function (value) {
+      return value != null;
+    });
 
-    customActions.forEach(function(action){
-      it(action + ' should be present in App.MainServiceItemView mastersExcludedCommands object', function() {
+    customActions.forEach(function (action) {
+      it(action + ' should be present in App.MainServiceItemView mastersExcludedCommands object', function () {
         expect(allMastersExcludedCommands).to.contain(action);
       });
     });
   });
+
+  describe('#observeMaintenance', function () {
+
+    var mastersExcludedCommands = {
+        NAMENODE: ["DECOMMISSION", "REBALANCEHDFS"],
+        RESOURCEMANAGER: ["DECOMMISSION", "REFRESHQUEUES"],
+        HBASE_MASTER: ["DECOMMISSION"],
+        KNOX_GATEWAY: ["STARTDEMOLDAP", "STOPDEMOLDAP"]
+      },
+      hasConfigTab = true,
+      testCases = [
+        {
+          serviceName: "HDFS",
+          displayName: "HDFS",
+          serviceTypes: ["HA_MODE"],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'DATANODE',
+              isMaster: false,
+              isSlave: true
+            }),
+            Em.Object.create({
+              componentName: 'HDFS_CLIENT',
+              isMaster: false,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'NAMENODE',
+              isMaster: true,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'SECONDARY_NAMENODE',
+              isMaster: true,
+              isSlave: false
+            })
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "HDFS", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "rollingRestart", "label": "Restart DataNodes", "cssClass": "icon-time", "disabled": false, "context": "DATANODE"},
+            {"action": "reassignMaster", "context": "NAMENODE", "label": "Move NameNode", "cssClass": "icon-share-alt", "disabled": false},
+            {"action": "reassignMaster", "context": "SECONDARY_NAMENODE", "label": "Move SNameNode", "cssClass": "icon-share-alt", "disabled": false},
+            {"action": "enableHighAvailability", "label": "Enable NameNode HA", "cssClass": "icon-arrow-up", "isHidden": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for HDFS", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"action": "rebalanceHdfsNodes", "customCommand": "REBALANCEHDFS", "context": "Rebalance HDFS", "label": "Rebalance HDFS", "cssClass": "icon-refresh", "disabled": false},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, hasSubmenu: false, submenuOptions: []}
+          ]
+        },
+        {
+          serviceName: "ZOOKEEPER",
+          displayName: "ZooKeeper",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'ZOOKEEPER_CLIENT',
+              isMaster: false,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'ZOOKEEPER_SERVER',
+              isMaster: true,
+              isSlave: false
+            })
+          ],
+          controller: [
+            {'addDisabledTooltipZOOKEEPER_SERVER': ''},
+            {'isAddDisabled-ZOOKEEPER_SERVER': 'disabled'}
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "ZOOKEEPER", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for ZooKeeper", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"cssClass": "icon-plus", "label": "Add ZooKeeper Server", "service": "ZOOKEEPER", "component": "ZOOKEEPER_SERVER", "action": "addZOOKEEPER_SERVER", "disabled": "disabled", tooltip: ''},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "YARN",
+          displayName: "YARN",
+          serviceTypes: ['HA_MODE'],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'APP_TIMELINE_SERVER',
+              isMaster: true,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'NODEMANAGER',
+              isMaster: false,
+              isSlave: true
+            }),
+            Em.Object.create({
+              componentName: 'RESOURCEMANAGER',
+              isMaster: true,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'YARN_CLIENT',
+              isMaster: false,
+              isSlave: false
+            })
+          ],
+          result: [
+            {"action": "refreshYarnQueues", "customCommand": "REFRESHQUEUES", "label": "Refresh YARN Capacity Scheduler", "cssClass": "icon-refresh", "disabled": false},
+            {"action": "restartAllHostComponents", "context": "YARN", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "rollingRestart", "label": "Restart NodeManagers", "cssClass": "icon-time", "disabled": false, "context": "NODEMANAGER"},
+            {"action": "reassignMaster", "context": "APP_TIMELINE_SERVER", "label": "Move App Timeline Server", "cssClass": "icon-share-alt", "disabled": false},
+            {"action": "reassignMaster", "context": "RESOURCEMANAGER", "label": "Move ResourceManager", "cssClass": "icon-share-alt", "disabled": false},
+            {"action": "enableRMHighAvailability", "label": "Enable ResourceManager HA", "cssClass": "icon-arrow-up", "isHidden": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for YARN", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "MAPREDUCE2",
+          displayName: "MapReduce2",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'HISTORYSERVER',
+              isMaster: true,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'MAPREDUCE2_CLIENT',
+              isMaster: false,
+              isSlave: false
+            })
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "MAPREDUCE2", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for MapReduce2", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "KAFKA",
+          displayName: "Kafka",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'KAFKA_BROKER',
+              isMaster: true,
+              isSlave: false
+            })
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "KAFKA", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for Kafka", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "FLUME",
+          displayName: "Flume",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'FLUME_HANDLER',
+              isMaster: false,
+              isSlave: true
+            })
+          ],
+          controller: [
+            {'addDisabledTooltipFLUME_HANDLER': ''},
+            {'isAddDisabled-FLUME_HANDLER': ''}
+          ],
+          result: [
+            {"action": "refreshConfigs", "label": "Refresh configs", "cssClass": "icon-refresh", "disabled": true},
+            {"action": "restartAllHostComponents", "context": "FLUME", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "rollingRestart", "label": "Restart Flumes", "cssClass": "icon-time", "disabled": false, "context": "FLUME_HANDLER"},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for Flume", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"cssClass": "icon-plus", "label": "Add Flume Component", "service": "FLUME", "component": "FLUME_HANDLER", "action": "addFLUME_HANDLER", "disabled": '', tooltip: ''},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "HBASE",
+          displayName: "HBase",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'HBASE_CLIENT',
+              isMaster: false,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'HBASE_MASTER',
+              isMaster: true,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'HBASE_REGIONSERVER',
+              isMaster: false,
+              isSlave: true
+            })
+          ],
+          controller: [
+            {'addDisabledTooltipHBASE_MASTER': ''},
+            {'isAddDisabled-HBASE_MASTER': ''}
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "HBASE", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "rollingRestart", "label": "Restart RegionServers", "cssClass": "icon-time", "disabled": false, "context": "HBASE_REGIONSERVER"},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for HBase", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"cssClass": "icon-plus", "label": "Add HBase Master", "service": "HBASE", "component": "HBASE_MASTER", "action": "addHBASE_MASTER", "disabled": '', tooltip: ''},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "OOZIE",
+          displayName: "Oozie",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'OOZIE_CLIENT',
+              isMaster: false,
+              isSlave: false
+            }),
+            Em.Object.create({
+              componentName: 'OOZIE_SERVER',
+              isMaster: true,
+              isSlave: false
+            })
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "OOZIE", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "reassignMaster", "context": "OOZIE_SERVER", "label": "Move Oozie Server", "cssClass": "icon-share-alt", "disabled": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for Oozie", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        },
+        {
+          serviceName: "KNOX",
+          displayName: "Knox",
+          serviceTypes: [],
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'KNOX_GATEWAY',
+              isMaster: true,
+              isSlave: false
+            })
+          ],
+          result: [
+            {"action": "restartAllHostComponents", "context": "KNOX", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false},
+            {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt"},
+            {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for Knox", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false},
+            {"action": "startLdapKnox", "customCommand": "STARTDEMOLDAP", "label": "Start Demo LDAP", "cssClass": "icon-play-sign", "disabled": false},
+            {"action": "stopLdapKnox", "customCommand": "STOPDEMOLDAP", "label": "Stop Demo LDAP", "cssClass": "icon-stop", "disabled": false},
+            {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []}
+          ]
+        }
+      ];
+
+    beforeEach(function () {
+
+      sinon.stub(App, 'get', function (k) {
+        switch (k) {
+          case 'components.rollinRestartAllowed':
+            return ["DATANODE", "JOURNALNODE", "ZKFC", "NODEMANAGER", "GANGLIA_MONITOR", "HBASE_REGIONSERVER", "SUPERVISOR", "FLUME_HANDLER"];
+          case 'components.reassignable':
+            return ["NAMENODE", "SECONDARY_NAMENODE", "APP_TIMELINE_SERVER", "RESOURCEMANAGER", "WEBHCAT_SERVER", "OOZIE_SERVER"];
+          case 'services.supportsServiceCheck':
+            return ["HDFS", "MAPREDUCE2", "YARN", "HIVE", "HBASE", "PIG", "SQOOP", "OOZIE", "ZOOKEEPER", "FALCON", "STORM", "FLUME", "SLIDER", "KNOX", "KAFKA"];
+          default:
+            return Em.get(App, k);
+        }
+      });
+
+      sinon.stub(App.StackServiceComponent, 'find', function () {
+        switch (arguments[0]) {
+          case 'NAMENODE':
+            return Em.Object.create({ customCommands: ["DECOMMISSION", "REBALANCEHDFS"] });
+          case 'RESOURCEMANAGER':
+            return Em.Object.create({ customCommands: ["DECOMMISSION", "REFRESHQUEUES"] });
+          case 'HBASE_MASTER':
+            return Em.Object.create({ customCommands: ["DECOMMISSION"] });
+          case 'KNOX_GATEWAY':
+            return Em.Object.create({ customCommands: ["STARTDEMOLDAP", "STOPDEMOLDAP"] });
+          case 'HISTORYSERVER':
+          case 'SECONDARY_NAMENODE':
+          case 'ZOOKEEPER_SERVER':
+          case 'APP_TIMELINE_SERVER':
+          case 'KAFKA_BROKER':
+          case 'OOZIE_SERVER':
+            return Em.Object.create({ customCommands: [] });
+          default:
+            return [
+              Em.Object.create({
+                customCommands: ["DECOMMISSION", "REBALANCEHDFS"],
+                componentName: 'NAMENODE'
+              }),
+              Em.Object.create({
+                customCommands: ["STARTDEMOLDAP", "STOPDEMOLDAP"],
+                componentName: 'KNOX_GATEWAY'
+              })
+            ];
+        }
+      });
+    });
+
+    afterEach(function () {
+      App.get.restore();
+      App.StackServiceComponent.find.restore();
+    });
+
+    testCases.forEach(function (testCase) {
+
+      var view = App.MainServiceItemView.create({
+        controller: Em.Object.create({
+          content: Em.Object.create({})
+        })
+      });
+
+      it('Maintenance for ' + testCase.serviceName + ' service', function () {
+        view.set('controller.content', Em.Object.create({
+          hostComponents: testCase.hostComponents,
+          serviceName: testCase.serviceName,
+          displayName: testCase.displayName,
+          serviceTypes: testCase.serviceTypes,
+          passiveState: 'OFF'
+        }));
+        if (testCase.controller) {
+          testCase.controller.forEach(function (item) {
+            Object.keys(item).forEach(function (key) {
+              view.set('controller.' + key, item[key]);
+            });
+          });
+        }
+        view.set('controller.isSeveralClients', false);
+        view.set('controller.clientComponents', []);
+        view.set('mastersExcludedCommands', mastersExcludedCommands);
+        view.set('hasConfigTab', hasConfigTab);
+        view.observeMaintenanceOnce();
+        expect(view.get('maintenance')).to.eql(testCase.result);
+      });
+
+      it('Change isPassive option in maintenance for ' + testCase.serviceName + ' service', function () {
+        var oldMaintenance = JSON.parse(JSON.stringify(view.maintenance));
+        view.set('controller.content.passiveState', 'ON');
+        view.observeMaintenanceOnce();
+        expect(view.get('maintenance')).to.not.eql(oldMaintenance);
+      });
+
+    });
+  });
 });
 


[04/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/draggable.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/draggable.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/draggable.js
new file mode 100644
index 0000000..722fa7f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/draggable.js
@@ -0,0 +1,1128 @@
+/*!
+ * jQuery UI Draggable 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/draggable/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define([
+			"jquery",
+			"./core",
+			"./mouse",
+			"./widget"
+		], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+$.widget("ui.draggable", $.ui.mouse, {
+	version: "1.11.2",
+	widgetEventPrefix: "drag",
+	options: {
+		addClasses: true,
+		appendTo: "parent",
+		axis: false,
+		connectToSortable: false,
+		containment: false,
+		cursor: "auto",
+		cursorAt: false,
+		grid: false,
+		handle: false,
+		helper: "original",
+		iframeFix: false,
+		opacity: false,
+		refreshPositions: false,
+		revert: false,
+		revertDuration: 500,
+		scope: "default",
+		scroll: true,
+		scrollSensitivity: 20,
+		scrollSpeed: 20,
+		snap: false,
+		snapMode: "both",
+		snapTolerance: 20,
+		stack: false,
+		zIndex: false,
+
+		// callbacks
+		drag: null,
+		start: null,
+		stop: null
+	},
+	_create: function() {
+
+		if ( this.options.helper === "original" ) {
+			this._setPositionRelative();
+		}
+		if (this.options.addClasses){
+			this.element.addClass("ui-draggable");
+		}
+		if (this.options.disabled){
+			this.element.addClass("ui-draggable-disabled");
+		}
+		this._setHandleClassName();
+
+		this._mouseInit();
+	},
+
+	_setOption: function( key, value ) {
+		this._super( key, value );
+		if ( key === "handle" ) {
+			this._removeHandleClassName();
+			this._setHandleClassName();
+		}
+	},
+
+	_destroy: function() {
+		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
+			this.destroyOnClear = true;
+			return;
+		}
+		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
+		this._removeHandleClassName();
+		this._mouseDestroy();
+	},
+
+	_mouseCapture: function(event) {
+		var o = this.options;
+
+		this._blurActiveElement( event );
+
+		// among others, prevent a drag on a resizable-handle
+		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
+			return false;
+		}
+
+		//Quit if we're not on a valid handle
+		this.handle = this._getHandle(event);
+		if (!this.handle) {
+			return false;
+		}
+
+		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
+
+		return true;
+
+	},
+
+	_blockFrames: function( selector ) {
+		this.iframeBlocks = this.document.find( selector ).map(function() {
+			var iframe = $( this );
+
+			return $( "<div>" )
+				.css( "position", "absolute" )
+				.appendTo( iframe.parent() )
+				.outerWidth( iframe.outerWidth() )
+				.outerHeight( iframe.outerHeight() )
+				.offset( iframe.offset() )[ 0 ];
+		});
+	},
+
+	_unblockFrames: function() {
+		if ( this.iframeBlocks ) {
+			this.iframeBlocks.remove();
+			delete this.iframeBlocks;
+		}
+	},
+
+	_blurActiveElement: function( event ) {
+		var document = this.document[ 0 ];
+
+		// Only need to blur if the event occurred on the draggable itself, see #10527
+		if ( !this.handleElement.is( event.target ) ) {
+			return;
+		}
+
+		// support: IE9
+		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+		try {
+
+			// Support: IE9, IE10
+			// If the <body> is blurred, IE will switch windows, see #9520
+			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
+
+				// Blur any element that currently has focus, see #4261
+				$( document.activeElement ).blur();
+			}
+		} catch ( error ) {}
+	},
+
+	_mouseStart: function(event) {
+
+		var o = this.options;
+
+		//Create and append the visible helper
+		this.helper = this._createHelper(event);
+
+		this.helper.addClass("ui-draggable-dragging");
+
+		//Cache the helper size
+		this._cacheHelperProportions();
+
+		//If ddmanager is used for droppables, set the global draggable
+		if ($.ui.ddmanager) {
+			$.ui.ddmanager.current = this;
+		}
+
+		/*
+		 * - Position generation -
+		 * This block generates everything position related - it's the core of draggables.
+		 */
+
+		//Cache the margins of the original element
+		this._cacheMargins();
+
+		//Store the helper's css position
+		this.cssPosition = this.helper.css( "position" );
+		this.scrollParent = this.helper.scrollParent( true );
+		this.offsetParent = this.helper.offsetParent();
+		this.hasFixedAncestor = this.helper.parents().filter(function() {
+				return $( this ).css( "position" ) === "fixed";
+			}).length > 0;
+
+		//The element's absolute position on the page minus margins
+		this.positionAbs = this.element.offset();
+		this._refreshOffsets( event );
+
+		//Generate the original position
+		this.originalPosition = this.position = this._generatePosition( event, false );
+		this.originalPageX = event.pageX;
+		this.originalPageY = event.pageY;
+
+		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+		//Set a containment if given in the options
+		this._setContainment();
+
+		//Trigger event + callbacks
+		if (this._trigger("start", event) === false) {
+			this._clear();
+			return false;
+		}
+
+		//Recache the helper size
+		this._cacheHelperProportions();
+
+		//Prepare the droppable offsets
+		if ($.ui.ddmanager && !o.dropBehaviour) {
+			$.ui.ddmanager.prepareOffsets(this, event);
+		}
+
+		// Reset helper's right/bottom css if they're set and set explicit width/height instead
+		// as this prevents resizing of elements with right/bottom set (see #7772)
+		this._normalizeRightBottom();
+
+		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+
+		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.dragStart(this, event);
+		}
+
+		return true;
+	},
+
+	_refreshOffsets: function( event ) {
+		this.offset = {
+			top: this.positionAbs.top - this.margins.top,
+			left: this.positionAbs.left - this.margins.left,
+			scroll: false,
+			parent: this._getParentOffset(),
+			relative: this._getRelativeOffset()
+		};
+
+		this.offset.click = {
+			left: event.pageX - this.offset.left,
+			top: event.pageY - this.offset.top
+		};
+	},
+
+	_mouseDrag: function(event, noPropagation) {
+		// reset any necessary cached properties (see #5009)
+		if ( this.hasFixedAncestor ) {
+			this.offset.parent = this._getParentOffset();
+		}
+
+		//Compute the helpers position
+		this.position = this._generatePosition( event, true );
+		this.positionAbs = this._convertPositionTo("absolute");
+
+		//Call plugins and callbacks and use the resulting position if something is returned
+		if (!noPropagation) {
+			var ui = this._uiHash();
+			if (this._trigger("drag", event, ui) === false) {
+				this._mouseUp({});
+				return false;
+			}
+			this.position = ui.position;
+		}
+
+		this.helper[ 0 ].style.left = this.position.left + "px";
+		this.helper[ 0 ].style.top = this.position.top + "px";
+
+		if ($.ui.ddmanager) {
+			$.ui.ddmanager.drag(this, event);
+		}
+
+		return false;
+	},
+
+	_mouseStop: function(event) {
+
+		//If we are using droppables, inform the manager about the drop
+		var that = this,
+			dropped = false;
+		if ($.ui.ddmanager && !this.options.dropBehaviour) {
+			dropped = $.ui.ddmanager.drop(this, event);
+		}
+
+		//if a drop comes from outside (a sortable)
+		if (this.dropped) {
+			dropped = this.dropped;
+			this.dropped = false;
+		}
+
+		if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+				if (that._trigger("stop", event) !== false) {
+					that._clear();
+				}
+			});
+		} else {
+			if (this._trigger("stop", event) !== false) {
+				this._clear();
+			}
+		}
+
+		return false;
+	},
+
+	_mouseUp: function( event ) {
+		this._unblockFrames();
+
+		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.dragStop(this, event);
+		}
+
+		// Only need to focus if the event occurred on the draggable itself, see #10527
+		if ( this.handleElement.is( event.target ) ) {
+			// The interaction is over; whether or not the click resulted in a drag, focus the element
+			this.element.focus();
+		}
+
+		return $.ui.mouse.prototype._mouseUp.call(this, event);
+	},
+
+	cancel: function() {
+
+		if (this.helper.is(".ui-draggable-dragging")) {
+			this._mouseUp({});
+		} else {
+			this._clear();
+		}
+
+		return this;
+
+	},
+
+	_getHandle: function(event) {
+		return this.options.handle ?
+			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
+			true;
+	},
+
+	_setHandleClassName: function() {
+		this.handleElement = this.options.handle ?
+			this.element.find( this.options.handle ) : this.element;
+		this.handleElement.addClass( "ui-draggable-handle" );
+	},
+
+	_removeHandleClassName: function() {
+		this.handleElement.removeClass( "ui-draggable-handle" );
+	},
+
+	_createHelper: function(event) {
+
+		var o = this.options,
+			helperIsFunction = $.isFunction( o.helper ),
+			helper = helperIsFunction ?
+				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
+				( o.helper === "clone" ?
+					this.element.clone().removeAttr( "id" ) :
+					this.element );
+
+		if (!helper.parents("body").length) {
+			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
+		}
+
+		// http://bugs.jqueryui.com/ticket/9446
+		// a helper function can return the original element
+		// which wouldn't have been set to relative in _create
+		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
+			this._setPositionRelative();
+		}
+
+		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
+			helper.css("position", "absolute");
+		}
+
+		return helper;
+
+	},
+
+	_setPositionRelative: function() {
+		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
+			this.element[ 0 ].style.position = "relative";
+		}
+	},
+
+	_adjustOffsetFromHelper: function(obj) {
+		if (typeof obj === "string") {
+			obj = obj.split(" ");
+		}
+		if ($.isArray(obj)) {
+			obj = { left: +obj[0], top: +obj[1] || 0 };
+		}
+		if ("left" in obj) {
+			this.offset.click.left = obj.left + this.margins.left;
+		}
+		if ("right" in obj) {
+			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+		}
+		if ("top" in obj) {
+			this.offset.click.top = obj.top + this.margins.top;
+		}
+		if ("bottom" in obj) {
+			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+		}
+	},
+
+	_isRootNode: function( element ) {
+		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
+	},
+
+	_getParentOffset: function() {
+
+		//Get the offsetParent and cache its position
+		var po = this.offsetParent.offset(),
+			document = this.document[ 0 ];
+
+		// This is a special case where we need to modify a offset calculated on start, since the following happened:
+		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+			po.left += this.scrollParent.scrollLeft();
+			po.top += this.scrollParent.scrollTop();
+		}
+
+		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
+			po = { top: 0, left: 0 };
+		}
+
+		return {
+			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
+			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
+		};
+
+	},
+
+	_getRelativeOffset: function() {
+		if ( this.cssPosition !== "relative" ) {
+			return { top: 0, left: 0 };
+		}
+
+		var p = this.element.position(),
+			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+		return {
+			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
+			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
+		};
+
+	},
+
+	_cacheMargins: function() {
+		this.margins = {
+			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
+			top: (parseInt(this.element.css("marginTop"), 10) || 0),
+			right: (parseInt(this.element.css("marginRight"), 10) || 0),
+			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
+		};
+	},
+
+	_cacheHelperProportions: function() {
+		this.helperProportions = {
+			width: this.helper.outerWidth(),
+			height: this.helper.outerHeight()
+		};
+	},
+
+	_setContainment: function() {
+
+		var isUserScrollable, c, ce,
+			o = this.options,
+			document = this.document[ 0 ];
+
+		this.relativeContainer = null;
+
+		if ( !o.containment ) {
+			this.containment = null;
+			return;
+		}
+
+		if ( o.containment === "window" ) {
+			this.containment = [
+				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
+				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+			];
+			return;
+		}
+
+		if ( o.containment === "document") {
+			this.containment = [
+				0,
+				0,
+				$( document ).width() - this.helperProportions.width - this.margins.left,
+				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+			];
+			return;
+		}
+
+		if ( o.containment.constructor === Array ) {
+			this.containment = o.containment;
+			return;
+		}
+
+		if ( o.containment === "parent" ) {
+			o.containment = this.helper[ 0 ].parentNode;
+		}
+
+		c = $( o.containment );
+		ce = c[ 0 ];
+
+		if ( !ce ) {
+			return;
+		}
+
+		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
+
+		this.containment = [
+			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
+			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
+			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
+				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
+				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
+				this.helperProportions.width -
+				this.margins.left -
+				this.margins.right,
+			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
+				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
+				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
+				this.helperProportions.height -
+				this.margins.top -
+				this.margins.bottom
+		];
+		this.relativeContainer = c;
+	},
+
+	_convertPositionTo: function(d, pos) {
+
+		if (!pos) {
+			pos = this.position;
+		}
+
+		var mod = d === "absolute" ? 1 : -1,
+			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+		return {
+			top: (
+				pos.top	+																// The absolute mouse position
+				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
+				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
+			),
+			left: (
+				pos.left +																// The absolute mouse position
+				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
+				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
+			)
+		};
+
+	},
+
+	_generatePosition: function( event, constrainPosition ) {
+
+		var containment, co, top, left,
+			o = this.options,
+			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
+			pageX = event.pageX,
+			pageY = event.pageY;
+
+		// Cache the scroll
+		if ( !scrollIsRootNode || !this.offset.scroll ) {
+			this.offset.scroll = {
+				top: this.scrollParent.scrollTop(),
+				left: this.scrollParent.scrollLeft()
+			};
+		}
+
+		/*
+		 * - Position constraining -
+		 * Constrain the position to a mix of grid, containment.
+		 */
+
+		// If we are not dragging yet, we won't check for options
+		if ( constrainPosition ) {
+			if ( this.containment ) {
+				if ( this.relativeContainer ){
+					co = this.relativeContainer.offset();
+					containment = [
+						this.containment[ 0 ] + co.left,
+						this.containment[ 1 ] + co.top,
+						this.containment[ 2 ] + co.left,
+						this.containment[ 3 ] + co.top
+					];
+				} else {
+					containment = this.containment;
+				}
+
+				if (event.pageX - this.offset.click.left < containment[0]) {
+					pageX = containment[0] + this.offset.click.left;
+				}
+				if (event.pageY - this.offset.click.top < containment[1]) {
+					pageY = containment[1] + this.offset.click.top;
+				}
+				if (event.pageX - this.offset.click.left > containment[2]) {
+					pageX = containment[2] + this.offset.click.left;
+				}
+				if (event.pageY - this.offset.click.top > containment[3]) {
+					pageY = containment[3] + this.offset.click.top;
+				}
+			}
+
+			if (o.grid) {
+				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
+				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
+				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
+				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+			}
+
+			if ( o.axis === "y" ) {
+				pageX = this.originalPageX;
+			}
+
+			if ( o.axis === "x" ) {
+				pageY = this.originalPageY;
+			}
+		}
+
+		return {
+			top: (
+				pageY -																	// The absolute mouse position
+				this.offset.click.top	-												// Click offset (relative to the element)
+				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
+				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
+			),
+			left: (
+				pageX -																	// The absolute mouse position
+				this.offset.click.left -												// Click offset (relative to the element)
+				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
+				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
+			)
+		};
+
+	},
+
+	_clear: function() {
+		this.helper.removeClass("ui-draggable-dragging");
+		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
+			this.helper.remove();
+		}
+		this.helper = null;
+		this.cancelHelperRemoval = false;
+		if ( this.destroyOnClear ) {
+			this.destroy();
+		}
+	},
+
+	_normalizeRightBottom: function() {
+		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
+			this.helper.width( this.helper.width() );
+			this.helper.css( "right", "auto" );
+		}
+		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
+			this.helper.height( this.helper.height() );
+			this.helper.css( "bottom", "auto" );
+		}
+	},
+
+	// From now on bulk stuff - mainly helpers
+
+	_trigger: function( type, event, ui ) {
+		ui = ui || this._uiHash();
+		$.ui.plugin.call( this, type, [ event, ui, this ], true );
+
+		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
+		if ( /^(drag|start|stop)/.test( type ) ) {
+			this.positionAbs = this._convertPositionTo( "absolute" );
+			ui.offset = this.positionAbs;
+		}
+		return $.Widget.prototype._trigger.call( this, type, event, ui );
+	},
+
+	plugins: {},
+
+	_uiHash: function() {
+		return {
+			helper: this.helper,
+			position: this.position,
+			originalPosition: this.originalPosition,
+			offset: this.positionAbs
+		};
+	}
+
+});
+
+$.ui.plugin.add( "draggable", "connectToSortable", {
+	start: function( event, ui, draggable ) {
+		var uiSortable = $.extend( {}, ui, {
+			item: draggable.element
+		});
+
+		draggable.sortables = [];
+		$( draggable.options.connectToSortable ).each(function() {
+			var sortable = $( this ).sortable( "instance" );
+
+			if ( sortable && !sortable.options.disabled ) {
+				draggable.sortables.push( sortable );
+
+				// refreshPositions is called at drag start to refresh the containerCache
+				// which is used in drag. This ensures it's initialized and synchronized
+				// with any changes that might have happened on the page since initialization.
+				sortable.refreshPositions();
+				sortable._trigger("activate", event, uiSortable);
+			}
+		});
+	},
+	stop: function( event, ui, draggable ) {
+		var uiSortable = $.extend( {}, ui, {
+			item: draggable.element
+		});
+
+		draggable.cancelHelperRemoval = false;
+
+		$.each( draggable.sortables, function() {
+			var sortable = this;
+
+			if ( sortable.isOver ) {
+				sortable.isOver = 0;
+
+				// Allow this sortable to handle removing the helper
+				draggable.cancelHelperRemoval = true;
+				sortable.cancelHelperRemoval = false;
+
+				// Use _storedCSS To restore properties in the sortable,
+				// as this also handles revert (#9675) since the draggable
+				// may have modified them in unexpected ways (#8809)
+				sortable._storedCSS = {
+					position: sortable.placeholder.css( "position" ),
+					top: sortable.placeholder.css( "top" ),
+					left: sortable.placeholder.css( "left" )
+				};
+
+				sortable._mouseStop(event);
+
+				// Once drag has ended, the sortable should return to using
+				// its original helper, not the shared helper from draggable
+				sortable.options.helper = sortable.options._helper;
+			} else {
+				// Prevent this Sortable from removing the helper.
+				// However, don't set the draggable to remove the helper
+				// either as another connected Sortable may yet handle the removal.
+				sortable.cancelHelperRemoval = true;
+
+				sortable._trigger( "deactivate", event, uiSortable );
+			}
+		});
+	},
+	drag: function( event, ui, draggable ) {
+		$.each( draggable.sortables, function() {
+			var innermostIntersecting = false,
+				sortable = this;
+
+			// Copy over variables that sortable's _intersectsWith uses
+			sortable.positionAbs = draggable.positionAbs;
+			sortable.helperProportions = draggable.helperProportions;
+			sortable.offset.click = draggable.offset.click;
+
+			if ( sortable._intersectsWith( sortable.containerCache ) ) {
+				innermostIntersecting = true;
+
+				$.each( draggable.sortables, function() {
+					// Copy over variables that sortable's _intersectsWith uses
+					this.positionAbs = draggable.positionAbs;
+					this.helperProportions = draggable.helperProportions;
+					this.offset.click = draggable.offset.click;
+
+					if ( this !== sortable &&
+							this._intersectsWith( this.containerCache ) &&
+							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
+						innermostIntersecting = false;
+					}
+
+					return innermostIntersecting;
+				});
+			}
+
+			if ( innermostIntersecting ) {
+				// If it intersects, we use a little isOver variable and set it once,
+				// so that the move-in stuff gets fired only once.
+				if ( !sortable.isOver ) {
+					sortable.isOver = 1;
+
+					sortable.currentItem = ui.helper
+						.appendTo( sortable.element )
+						.data( "ui-sortable-item", true );
+
+					// Store helper option to later restore it
+					sortable.options._helper = sortable.options.helper;
+
+					sortable.options.helper = function() {
+						return ui.helper[ 0 ];
+					};
+
+					// Fire the start events of the sortable with our passed browser event,
+					// and our own helper (so it doesn't create a new one)
+					event.target = sortable.currentItem[ 0 ];
+					sortable._mouseCapture( event, true );
+					sortable._mouseStart( event, true, true );
+
+					// Because the browser event is way off the new appended portlet,
+					// modify necessary variables to reflect the changes
+					sortable.offset.click.top = draggable.offset.click.top;
+					sortable.offset.click.left = draggable.offset.click.left;
+					sortable.offset.parent.left -= draggable.offset.parent.left -
+						sortable.offset.parent.left;
+					sortable.offset.parent.top -= draggable.offset.parent.top -
+						sortable.offset.parent.top;
+
+					draggable._trigger( "toSortable", event );
+
+					// Inform draggable that the helper is in a valid drop zone,
+					// used solely in the revert option to handle "valid/invalid".
+					draggable.dropped = sortable.element;
+
+					// Need to refreshPositions of all sortables in the case that
+					// adding to one sortable changes the location of the other sortables (#9675)
+					$.each( draggable.sortables, function() {
+						this.refreshPositions();
+					});
+
+					// hack so receive/update callbacks work (mostly)
+					draggable.currentItem = draggable.element;
+					sortable.fromOutside = draggable;
+				}
+
+				if ( sortable.currentItem ) {
+					sortable._mouseDrag( event );
+					// Copy the sortable's position because the draggable's can potentially reflect
+					// a relative position, while sortable is always absolute, which the dragged
+					// element has now become. (#8809)
+					ui.position = sortable.position;
+				}
+			} else {
+				// If it doesn't intersect with the sortable, and it intersected before,
+				// we fake the drag stop of the sortable, but make sure it doesn't remove
+				// the helper by using cancelHelperRemoval.
+				if ( sortable.isOver ) {
+
+					sortable.isOver = 0;
+					sortable.cancelHelperRemoval = true;
+
+					// Calling sortable's mouseStop would trigger a revert,
+					// so revert must be temporarily false until after mouseStop is called.
+					sortable.options._revert = sortable.options.revert;
+					sortable.options.revert = false;
+
+					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
+					sortable._mouseStop( event, true );
+
+					// restore sortable behaviors that were modfied
+					// when the draggable entered the sortable area (#9481)
+					sortable.options.revert = sortable.options._revert;
+					sortable.options.helper = sortable.options._helper;
+
+					if ( sortable.placeholder ) {
+						sortable.placeholder.remove();
+					}
+
+					// Recalculate the draggable's offset considering the sortable
+					// may have modified them in unexpected ways (#8809)
+					draggable._refreshOffsets( event );
+					ui.position = draggable._generatePosition( event, true );
+
+					draggable._trigger( "fromSortable", event );
+
+					// Inform draggable that the helper is no longer in a valid drop zone
+					draggable.dropped = false;
+
+					// Need to refreshPositions of all sortables just in case removing
+					// from one sortable changes the location of other sortables (#9675)
+					$.each( draggable.sortables, function() {
+						this.refreshPositions();
+					});
+				}
+			}
+		});
+	}
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+	start: function( event, ui, instance ) {
+		var t = $( "body" ),
+			o = instance.options;
+
+		if (t.css("cursor")) {
+			o._cursor = t.css("cursor");
+		}
+		t.css("cursor", o.cursor);
+	},
+	stop: function( event, ui, instance ) {
+		var o = instance.options;
+		if (o._cursor) {
+			$("body").css("cursor", o._cursor);
+		}
+	}
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+	start: function( event, ui, instance ) {
+		var t = $( ui.helper ),
+			o = instance.options;
+		if (t.css("opacity")) {
+			o._opacity = t.css("opacity");
+		}
+		t.css("opacity", o.opacity);
+	},
+	stop: function( event, ui, instance ) {
+		var o = instance.options;
+		if (o._opacity) {
+			$(ui.helper).css("opacity", o._opacity);
+		}
+	}
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+	start: function( event, ui, i ) {
+		if ( !i.scrollParentNotHidden ) {
+			i.scrollParentNotHidden = i.helper.scrollParent( false );
+		}
+
+		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
+			i.overflowOffset = i.scrollParentNotHidden.offset();
+		}
+	},
+	drag: function( event, ui, i  ) {
+
+		var o = i.options,
+			scrolled = false,
+			scrollParent = i.scrollParentNotHidden[ 0 ],
+			document = i.document[ 0 ];
+
+		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
+			if ( !o.axis || o.axis !== "x" ) {
+				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
+					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
+				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
+					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
+				}
+			}
+
+			if ( !o.axis || o.axis !== "y" ) {
+				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
+					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
+				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
+					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
+				}
+			}
+
+		} else {
+
+			if (!o.axis || o.axis !== "x") {
+				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
+					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
+					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+				}
+			}
+
+			if (!o.axis || o.axis !== "y") {
+				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
+					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
+					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+				}
+			}
+
+		}
+
+		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+			$.ui.ddmanager.prepareOffsets(i, event);
+		}
+
+	}
+});
+
+$.ui.plugin.add("draggable", "snap", {
+	start: function( event, ui, i ) {
+
+		var o = i.options;
+
+		i.snapElements = [];
+
+		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
+			var $t = $(this),
+				$o = $t.offset();
+			if (this !== i.element[0]) {
+				i.snapElements.push({
+					item: this,
+					width: $t.outerWidth(), height: $t.outerHeight(),
+					top: $o.top, left: $o.left
+				});
+			}
+		});
+
+	},
+	drag: function( event, ui, inst ) {
+
+		var ts, bs, ls, rs, l, r, t, b, i, first,
+			o = inst.options,
+			d = o.snapTolerance,
+			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+		for (i = inst.snapElements.length - 1; i >= 0; i--){
+
+			l = inst.snapElements[i].left - inst.margins.left;
+			r = l + inst.snapElements[i].width;
+			t = inst.snapElements[i].top - inst.margins.top;
+			b = t + inst.snapElements[i].height;
+
+			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
+				if (inst.snapElements[i].snapping) {
+					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+				}
+				inst.snapElements[i].snapping = false;
+				continue;
+			}
+
+			if (o.snapMode !== "inner") {
+				ts = Math.abs(t - y2) <= d;
+				bs = Math.abs(b - y1) <= d;
+				ls = Math.abs(l - x2) <= d;
+				rs = Math.abs(r - x1) <= d;
+				if (ts) {
+					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
+				}
+				if (bs) {
+					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
+				}
+				if (ls) {
+					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
+				}
+				if (rs) {
+					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
+				}
+			}
+
+			first = (ts || bs || ls || rs);
+
+			if (o.snapMode !== "outer") {
+				ts = Math.abs(t - y1) <= d;
+				bs = Math.abs(b - y2) <= d;
+				ls = Math.abs(l - x1) <= d;
+				rs = Math.abs(r - x2) <= d;
+				if (ts) {
+					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
+				}
+				if (bs) {
+					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
+				}
+				if (ls) {
+					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
+				}
+				if (rs) {
+					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
+				}
+			}
+
+			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
+				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+			}
+			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+		}
+
+	}
+});
+
+$.ui.plugin.add("draggable", "stack", {
+	start: function( event, ui, instance ) {
+		var min,
+			o = instance.options,
+			group = $.makeArray($(o.stack)).sort(function(a, b) {
+				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
+			});
+
+		if (!group.length) { return; }
+
+		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
+		$(group).each(function(i) {
+			$(this).css("zIndex", min + i);
+		});
+		this.css("zIndex", (min + group.length));
+	}
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+	start: function( event, ui, instance ) {
+		var t = $( ui.helper ),
+			o = instance.options;
+
+		if (t.css("zIndex")) {
+			o._zIndex = t.css("zIndex");
+		}
+		t.css("zIndex", o.zIndex);
+	},
+	stop: function( event, ui, instance ) {
+		var o = instance.options;
+
+		if (o._zIndex) {
+			$(ui.helper).css("zIndex", o._zIndex);
+		}
+	}
+});
+
+return $.ui.draggable;
+
+}));

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/droppable.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/droppable.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/droppable.js
new file mode 100644
index 0000000..341f6e1
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/droppable.js
@@ -0,0 +1,413 @@
+/*!
+ * jQuery UI Droppable 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/droppable/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define([
+			"jquery",
+			"./core",
+			"./widget",
+			"./mouse",
+			"./draggable"
+		], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+$.widget( "ui.droppable", {
+	version: "1.11.2",
+	widgetEventPrefix: "drop",
+	options: {
+		accept: "*",
+		activeClass: false,
+		addClasses: true,
+		greedy: false,
+		hoverClass: false,
+		scope: "default",
+		tolerance: "intersect",
+
+		// callbacks
+		activate: null,
+		deactivate: null,
+		drop: null,
+		out: null,
+		over: null
+	},
+	_create: function() {
+
+		var proportions,
+			o = this.options,
+			accept = o.accept;
+
+		this.isover = false;
+		this.isout = true;
+
+		this.accept = $.isFunction( accept ) ? accept : function( d ) {
+			return d.is( accept );
+		};
+
+		this.proportions = function( /* valueToWrite */ ) {
+			if ( arguments.length ) {
+				// Store the droppable's proportions
+				proportions = arguments[ 0 ];
+			} else {
+				// Retrieve or derive the droppable's proportions
+				return proportions ?
+					proportions :
+					proportions = {
+						width: this.element[ 0 ].offsetWidth,
+						height: this.element[ 0 ].offsetHeight
+					};
+			}
+		};
+
+		this._addToManager( o.scope );
+
+		o.addClasses && this.element.addClass( "ui-droppable" );
+
+	},
+
+	_addToManager: function( scope ) {
+		// Add the reference and positions to the manager
+		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
+		$.ui.ddmanager.droppables[ scope ].push( this );
+	},
+
+	_splice: function( drop ) {
+		var i = 0;
+		for ( ; i < drop.length; i++ ) {
+			if ( drop[ i ] === this ) {
+				drop.splice( i, 1 );
+			}
+		}
+	},
+
+	_destroy: function() {
+		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+		this._splice( drop );
+
+		this.element.removeClass( "ui-droppable ui-droppable-disabled" );
+	},
+
+	_setOption: function( key, value ) {
+
+		if ( key === "accept" ) {
+			this.accept = $.isFunction( value ) ? value : function( d ) {
+				return d.is( value );
+			};
+		} else if ( key === "scope" ) {
+			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+			this._splice( drop );
+			this._addToManager( value );
+		}
+
+		this._super( key, value );
+	},
+
+	_activate: function( event ) {
+		var draggable = $.ui.ddmanager.current;
+		if ( this.options.activeClass ) {
+			this.element.addClass( this.options.activeClass );
+		}
+		if ( draggable ){
+			this._trigger( "activate", event, this.ui( draggable ) );
+		}
+	},
+
+	_deactivate: function( event ) {
+		var draggable = $.ui.ddmanager.current;
+		if ( this.options.activeClass ) {
+			this.element.removeClass( this.options.activeClass );
+		}
+		if ( draggable ){
+			this._trigger( "deactivate", event, this.ui( draggable ) );
+		}
+	},
+
+	_over: function( event ) {
+
+		var draggable = $.ui.ddmanager.current;
+
+		// Bail if draggable and droppable are same element
+		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+			return;
+		}
+
+		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+			if ( this.options.hoverClass ) {
+				this.element.addClass( this.options.hoverClass );
+			}
+			this._trigger( "over", event, this.ui( draggable ) );
+		}
+
+	},
+
+	_out: function( event ) {
+
+		var draggable = $.ui.ddmanager.current;
+
+		// Bail if draggable and droppable are same element
+		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+			return;
+		}
+
+		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+			if ( this.options.hoverClass ) {
+				this.element.removeClass( this.options.hoverClass );
+			}
+			this._trigger( "out", event, this.ui( draggable ) );
+		}
+
+	},
+
+	_drop: function( event, custom ) {
+
+		var draggable = custom || $.ui.ddmanager.current,
+			childrenIntersection = false;
+
+		// Bail if draggable and droppable are same element
+		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+			return false;
+		}
+
+		this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
+			var inst = $( this ).droppable( "instance" );
+			if (
+				inst.options.greedy &&
+				!inst.options.disabled &&
+				inst.options.scope === draggable.options.scope &&
+				inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
+				$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
+			) { childrenIntersection = true; return false; }
+		});
+		if ( childrenIntersection ) {
+			return false;
+		}
+
+		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+			if ( this.options.activeClass ) {
+				this.element.removeClass( this.options.activeClass );
+			}
+			if ( this.options.hoverClass ) {
+				this.element.removeClass( this.options.hoverClass );
+			}
+			this._trigger( "drop", event, this.ui( draggable ) );
+			return this.element;
+		}
+
+		return false;
+
+	},
+
+	ui: function( c ) {
+		return {
+			draggable: ( c.currentItem || c.element ),
+			helper: c.helper,
+			position: c.position,
+			offset: c.positionAbs
+		};
+	}
+
+});
+
+$.ui.intersect = (function() {
+	function isOverAxis( x, reference, size ) {
+		return ( x >= reference ) && ( x < ( reference + size ) );
+	}
+
+	return function( draggable, droppable, toleranceMode, event ) {
+
+		if ( !droppable.offset ) {
+			return false;
+		}
+
+		var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
+			y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
+			x2 = x1 + draggable.helperProportions.width,
+			y2 = y1 + draggable.helperProportions.height,
+			l = droppable.offset.left,
+			t = droppable.offset.top,
+			r = l + droppable.proportions().width,
+			b = t + droppable.proportions().height;
+
+		switch ( toleranceMode ) {
+		case "fit":
+			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
+		case "intersect":
+			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
+				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
+				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
+				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
+		case "pointer":
+			return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
+		case "touch":
+			return (
+				( y1 >= t && y1 <= b ) || // Top edge touching
+				( y2 >= t && y2 <= b ) || // Bottom edge touching
+				( y1 < t && y2 > b ) // Surrounded vertically
+			) && (
+				( x1 >= l && x1 <= r ) || // Left edge touching
+				( x2 >= l && x2 <= r ) || // Right edge touching
+				( x1 < l && x2 > r ) // Surrounded horizontally
+			);
+		default:
+			return false;
+		}
+	};
+})();
+
+/*
+	This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+	current: null,
+	droppables: { "default": [] },
+	prepareOffsets: function( t, event ) {
+
+		var i, j,
+			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
+			type = event ? event.type : null, // workaround for #2317
+			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
+
+		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
+
+			// No disabled and non-accepted
+			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
+				continue;
+			}
+
+			// Filter out elements in the current dragged item
+			for ( j = 0; j < list.length; j++ ) {
+				if ( list[ j ] === m[ i ].element[ 0 ] ) {
+					m[ i ].proportions().height = 0;
+					continue droppablesLoop;
+				}
+			}
+
+			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
+			if ( !m[ i ].visible ) {
+				continue;
+			}
+
+			// Activate the droppable if used directly from draggables
+			if ( type === "mousedown" ) {
+				m[ i ]._activate.call( m[ i ], event );
+			}
+
+			m[ i ].offset = m[ i ].element.offset();
+			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
+
+		}
+
+	},
+	drop: function( draggable, event ) {
+
+		var dropped = false;
+		// Create a copy of the droppables in case the list changes during the drop (#9116)
+		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
+
+			if ( !this.options ) {
+				return;
+			}
+			if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
+				dropped = this._drop.call( this, event ) || dropped;
+			}
+
+			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+				this.isout = true;
+				this.isover = false;
+				this._deactivate.call( this, event );
+			}
+
+		});
+		return dropped;
+
+	},
+	dragStart: function( draggable, event ) {
+		// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
+		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
+			if ( !draggable.options.refreshPositions ) {
+				$.ui.ddmanager.prepareOffsets( draggable, event );
+			}
+		});
+	},
+	drag: function( draggable, event ) {
+
+		// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+		if ( draggable.options.refreshPositions ) {
+			$.ui.ddmanager.prepareOffsets( draggable, event );
+		}
+
+		// Run through all droppables and check their positions based on specific tolerance options
+		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
+
+			if ( this.options.disabled || this.greedyChild || !this.visible ) {
+				return;
+			}
+
+			var parentInstance, scope, parent,
+				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
+				c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
+			if ( !c ) {
+				return;
+			}
+
+			if ( this.options.greedy ) {
+				// find droppable parents with same scope
+				scope = this.options.scope;
+				parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
+					return $( this ).droppable( "instance" ).options.scope === scope;
+				});
+
+				if ( parent.length ) {
+					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
+					parentInstance.greedyChild = ( c === "isover" );
+				}
+			}
+
+			// we just moved into a greedy child
+			if ( parentInstance && c === "isover" ) {
+				parentInstance.isover = false;
+				parentInstance.isout = true;
+				parentInstance._out.call( parentInstance, event );
+			}
+
+			this[ c ] = true;
+			this[c === "isout" ? "isover" : "isout"] = false;
+			this[c === "isover" ? "_over" : "_out"].call( this, event );
+
+			// we just moved out of a greedy child
+			if ( parentInstance && c === "isout" ) {
+				parentInstance.isout = false;
+				parentInstance.isover = true;
+				parentInstance._over.call( parentInstance, event );
+			}
+		});
+
+	},
+	dragStop: function( draggable, event ) {
+		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
+		// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
+		if ( !draggable.options.refreshPositions ) {
+			$.ui.ddmanager.prepareOffsets( draggable, event );
+		}
+	}
+};
+
+return $.ui.droppable;
+
+}));

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/mouse.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/mouse.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/mouse.js
new file mode 100644
index 0000000..5304b98
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/mouse.js
@@ -0,0 +1,199 @@
+/*!
+ * jQuery UI Mouse 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/mouse/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define([
+			"jquery",
+			"./widget"
+		], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+var mouseHandled = false;
+$( document ).mouseup( function() {
+	mouseHandled = false;
+});
+
+return $.widget("ui.mouse", {
+	version: "1.11.2",
+	options: {
+		cancel: "input,textarea,button,select,option",
+		distance: 1,
+		delay: 0
+	},
+	_mouseInit: function() {
+		var that = this;
+
+		this.element
+			.bind("mousedown." + this.widgetName, function(event) {
+				return that._mouseDown(event);
+			})
+			.bind("click." + this.widgetName, function(event) {
+				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
+					$.removeData(event.target, that.widgetName + ".preventClickEvent");
+					event.stopImmediatePropagation();
+					return false;
+				}
+			});
+
+		this.started = false;
+	},
+
+	// TODO: make sure destroying one instance of mouse doesn't mess with
+	// other instances of mouse
+	_mouseDestroy: function() {
+		this.element.unbind("." + this.widgetName);
+		if ( this._mouseMoveDelegate ) {
+			this.document
+				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
+				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
+		}
+	},
+
+	_mouseDown: function(event) {
+		// don't let more than one widget handle mouseStart
+		if ( mouseHandled ) {
+			return;
+		}
+
+		this._mouseMoved = false;
+
+		// we may have missed mouseup (out of window)
+		(this._mouseStarted && this._mouseUp(event));
+
+		this._mouseDownEvent = event;
+
+		var that = this,
+			btnIsLeft = (event.which === 1),
+			// event.target.nodeName works around a bug in IE 8 with
+			// disabled inputs (#7620)
+			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+			return true;
+		}
+
+		this.mouseDelayMet = !this.options.delay;
+		if (!this.mouseDelayMet) {
+			this._mouseDelayTimer = setTimeout(function() {
+				that.mouseDelayMet = true;
+			}, this.options.delay);
+		}
+
+		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+			this._mouseStarted = (this._mouseStart(event) !== false);
+			if (!this._mouseStarted) {
+				event.preventDefault();
+				return true;
+			}
+		}
+
+		// Click event may never have fired (Gecko & Opera)
+		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
+			$.removeData(event.target, this.widgetName + ".preventClickEvent");
+		}
+
+		// these delegates are required to keep context
+		this._mouseMoveDelegate = function(event) {
+			return that._mouseMove(event);
+		};
+		this._mouseUpDelegate = function(event) {
+			return that._mouseUp(event);
+		};
+
+		this.document
+			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+		event.preventDefault();
+
+		mouseHandled = true;
+		return true;
+	},
+
+	_mouseMove: function(event) {
+		// Only check for mouseups outside the document if you've moved inside the document
+		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
+		// fire a mousemove event if content is placed under the cursor. See #7778
+		// Support: IE <9
+		if ( this._mouseMoved ) {
+			// IE mouseup check - mouseup happened when mouse was out of window
+			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
+				return this._mouseUp(event);
+
+			// Iframe mouseup check - mouseup occurred in another document
+			} else if ( !event.which ) {
+				return this._mouseUp( event );
+			}
+		}
+
+		if ( event.which || event.button ) {
+			this._mouseMoved = true;
+		}
+
+		if (this._mouseStarted) {
+			this._mouseDrag(event);
+			return event.preventDefault();
+		}
+
+		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+			this._mouseStarted =
+				(this._mouseStart(this._mouseDownEvent, event) !== false);
+			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+		}
+
+		return !this._mouseStarted;
+	},
+
+	_mouseUp: function(event) {
+		this.document
+			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+		if (this._mouseStarted) {
+			this._mouseStarted = false;
+
+			if (event.target === this._mouseDownEvent.target) {
+				$.data(event.target, this.widgetName + ".preventClickEvent", true);
+			}
+
+			this._mouseStop(event);
+		}
+
+		mouseHandled = false;
+		return false;
+	},
+
+	_mouseDistanceMet: function(event) {
+		return (Math.max(
+				Math.abs(this._mouseDownEvent.pageX - event.pageX),
+				Math.abs(this._mouseDownEvent.pageY - event.pageY)
+			) >= this.options.distance
+		);
+	},
+
+	_mouseDelayMet: function(/* event */) {
+		return this.mouseDelayMet;
+	},
+
+	// These are placeholder methods, to be overriden by extending plugin
+	_mouseStart: function(/* event */) {},
+	_mouseDrag: function(/* event */) {},
+	_mouseStop: function(/* event */) {},
+	_mouseCapture: function(/* event */) { return true; }
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/position.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/position.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/position.js
new file mode 100644
index 0000000..73be3f8
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/position.js
@@ -0,0 +1,517 @@
+/*!
+ * jQuery UI Position 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/position/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define( [ "jquery" ], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+(function() {
+
+$.ui = $.ui || {};
+
+var cachedScrollbarWidth, supportsOffsetFractions,
+	max = Math.max,
+	abs = Math.abs,
+	round = Math.round,
+	rhorizontal = /left|center|right/,
+	rvertical = /top|center|bottom/,
+	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
+	rposition = /^\w+/,
+	rpercent = /%$/,
+	_position = $.fn.position;
+
+function getOffsets( offsets, width, height ) {
+	return [
+		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
+		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
+	];
+}
+
+function parseCss( element, property ) {
+	return parseInt( $.css( element, property ), 10 ) || 0;
+}
+
+function getDimensions( elem ) {
+	var raw = elem[0];
+	if ( raw.nodeType === 9 ) {
+		return {
+			width: elem.width(),
+			height: elem.height(),
+			offset: { top: 0, left: 0 }
+		};
+	}
+	if ( $.isWindow( raw ) ) {
+		return {
+			width: elem.width(),
+			height: elem.height(),
+			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
+		};
+	}
+	if ( raw.preventDefault ) {
+		return {
+			width: 0,
+			height: 0,
+			offset: { top: raw.pageY, left: raw.pageX }
+		};
+	}
+	return {
+		width: elem.outerWidth(),
+		height: elem.outerHeight(),
+		offset: elem.offset()
+	};
+}
+
+$.position = {
+	scrollbarWidth: function() {
+		if ( cachedScrollbarWidth !== undefined ) {
+			return cachedScrollbarWidth;
+		}
+		var w1, w2,
+			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
+			innerDiv = div.children()[0];
+
+		$( "body" ).append( div );
+		w1 = innerDiv.offsetWidth;
+		div.css( "overflow", "scroll" );
+
+		w2 = innerDiv.offsetWidth;
+
+		if ( w1 === w2 ) {
+			w2 = div[0].clientWidth;
+		}
+
+		div.remove();
+
+		return (cachedScrollbarWidth = w1 - w2);
+	},
+	getScrollInfo: function( within ) {
+		var overflowX = within.isWindow || within.isDocument ? "" :
+				within.element.css( "overflow-x" ),
+			overflowY = within.isWindow || within.isDocument ? "" :
+				within.element.css( "overflow-y" ),
+			hasOverflowX = overflowX === "scroll" ||
+				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
+			hasOverflowY = overflowY === "scroll" ||
+				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
+		return {
+			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
+			height: hasOverflowX ? $.position.scrollbarWidth() : 0
+		};
+	},
+	getWithinInfo: function( element ) {
+		var withinElement = $( element || window ),
+			isWindow = $.isWindow( withinElement[0] ),
+			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
+		return {
+			element: withinElement,
+			isWindow: isWindow,
+			isDocument: isDocument,
+			offset: withinElement.offset() || { left: 0, top: 0 },
+			scrollLeft: withinElement.scrollLeft(),
+			scrollTop: withinElement.scrollTop(),
+
+			// support: jQuery 1.6.x
+			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
+			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
+			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
+		};
+	}
+};
+
+$.fn.position = function( options ) {
+	if ( !options || !options.of ) {
+		return _position.apply( this, arguments );
+	}
+
+	// make a copy, we don't want to modify arguments
+	options = $.extend( {}, options );
+
+	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
+		target = $( options.of ),
+		within = $.position.getWithinInfo( options.within ),
+		scrollInfo = $.position.getScrollInfo( within ),
+		collision = ( options.collision || "flip" ).split( " " ),
+		offsets = {};
+
+	dimensions = getDimensions( target );
+	if ( target[0].preventDefault ) {
+		// force left top to allow flipping
+		options.at = "left top";
+	}
+	targetWidth = dimensions.width;
+	targetHeight = dimensions.height;
+	targetOffset = dimensions.offset;
+	// clone to reuse original targetOffset later
+	basePosition = $.extend( {}, targetOffset );
+
+	// force my and at to have valid horizontal and vertical positions
+	// if a value is missing or invalid, it will be converted to center
+	$.each( [ "my", "at" ], function() {
+		var pos = ( options[ this ] || "" ).split( " " ),
+			horizontalOffset,
+			verticalOffset;
+
+		if ( pos.length === 1) {
+			pos = rhorizontal.test( pos[ 0 ] ) ?
+				pos.concat( [ "center" ] ) :
+				rvertical.test( pos[ 0 ] ) ?
+					[ "center" ].concat( pos ) :
+					[ "center", "center" ];
+		}
+		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
+		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
+
+		// calculate offsets
+		horizontalOffset = roffset.exec( pos[ 0 ] );
+		verticalOffset = roffset.exec( pos[ 1 ] );
+		offsets[ this ] = [
+			horizontalOffset ? horizontalOffset[ 0 ] : 0,
+			verticalOffset ? verticalOffset[ 0 ] : 0
+		];
+
+		// reduce to just the positions without the offsets
+		options[ this ] = [
+			rposition.exec( pos[ 0 ] )[ 0 ],
+			rposition.exec( pos[ 1 ] )[ 0 ]
+		];
+	});
+
+	// normalize collision option
+	if ( collision.length === 1 ) {
+		collision[ 1 ] = collision[ 0 ];
+	}
+
+	if ( options.at[ 0 ] === "right" ) {
+		basePosition.left += targetWidth;
+	} else if ( options.at[ 0 ] === "center" ) {
+		basePosition.left += targetWidth / 2;
+	}
+
+	if ( options.at[ 1 ] === "bottom" ) {
+		basePosition.top += targetHeight;
+	} else if ( options.at[ 1 ] === "center" ) {
+		basePosition.top += targetHeight / 2;
+	}
+
+	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
+	basePosition.left += atOffset[ 0 ];
+	basePosition.top += atOffset[ 1 ];
+
+	return this.each(function() {
+		var collisionPosition, using,
+			elem = $( this ),
+			elemWidth = elem.outerWidth(),
+			elemHeight = elem.outerHeight(),
+			marginLeft = parseCss( this, "marginLeft" ),
+			marginTop = parseCss( this, "marginTop" ),
+			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
+			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
+			position = $.extend( {}, basePosition ),
+			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
+
+		if ( options.my[ 0 ] === "right" ) {
+			position.left -= elemWidth;
+		} else if ( options.my[ 0 ] === "center" ) {
+			position.left -= elemWidth / 2;
+		}
+
+		if ( options.my[ 1 ] === "bottom" ) {
+			position.top -= elemHeight;
+		} else if ( options.my[ 1 ] === "center" ) {
+			position.top -= elemHeight / 2;
+		}
+
+		position.left += myOffset[ 0 ];
+		position.top += myOffset[ 1 ];
+
+		// if the browser doesn't support fractions, then round for consistent results
+		if ( !supportsOffsetFractions ) {
+			position.left = round( position.left );
+			position.top = round( position.top );
+		}
+
+		collisionPosition = {
+			marginLeft: marginLeft,
+			marginTop: marginTop
+		};
+
+		$.each( [ "left", "top" ], function( i, dir ) {
+			if ( $.ui.position[ collision[ i ] ] ) {
+				$.ui.position[ collision[ i ] ][ dir ]( position, {
+					targetWidth: targetWidth,
+					targetHeight: targetHeight,
+					elemWidth: elemWidth,
+					elemHeight: elemHeight,
+					collisionPosition: collisionPosition,
+					collisionWidth: collisionWidth,
+					collisionHeight: collisionHeight,
+					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
+					my: options.my,
+					at: options.at,
+					within: within,
+					elem: elem
+				});
+			}
+		});
+
+		if ( options.using ) {
+			// adds feedback as second argument to using callback, if present
+			using = function( props ) {
+				var left = targetOffset.left - position.left,
+					right = left + targetWidth - elemWidth,
+					top = targetOffset.top - position.top,
+					bottom = top + targetHeight - elemHeight,
+					feedback = {
+						target: {
+							element: target,
+							left: targetOffset.left,
+							top: targetOffset.top,
+							width: targetWidth,
+							height: targetHeight
+						},
+						element: {
+							element: elem,
+							left: position.left,
+							top: position.top,
+							width: elemWidth,
+							height: elemHeight
+						},
+						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
+						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
+					};
+				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
+					feedback.horizontal = "center";
+				}
+				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
+					feedback.vertical = "middle";
+				}
+				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
+					feedback.important = "horizontal";
+				} else {
+					feedback.important = "vertical";
+				}
+				options.using.call( this, props, feedback );
+			};
+		}
+
+		elem.offset( $.extend( position, { using: using } ) );
+	});
+};
+
+$.ui.position = {
+	fit: {
+		left: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
+				outerWidth = within.width,
+				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+				overLeft = withinOffset - collisionPosLeft,
+				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
+				newOverRight;
+
+			// element is wider than within
+			if ( data.collisionWidth > outerWidth ) {
+				// element is initially over the left side of within
+				if ( overLeft > 0 && overRight <= 0 ) {
+					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
+					position.left += overLeft - newOverRight;
+				// element is initially over right side of within
+				} else if ( overRight > 0 && overLeft <= 0 ) {
+					position.left = withinOffset;
+				// element is initially over both left and right sides of within
+				} else {
+					if ( overLeft > overRight ) {
+						position.left = withinOffset + outerWidth - data.collisionWidth;
+					} else {
+						position.left = withinOffset;
+					}
+				}
+			// too far left -> align with left edge
+			} else if ( overLeft > 0 ) {
+				position.left += overLeft;
+			// too far right -> align with right edge
+			} else if ( overRight > 0 ) {
+				position.left -= overRight;
+			// adjust based on position and margin
+			} else {
+				position.left = max( position.left - collisionPosLeft, position.left );
+			}
+		},
+		top: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
+				outerHeight = data.within.height,
+				collisionPosTop = position.top - data.collisionPosition.marginTop,
+				overTop = withinOffset - collisionPosTop,
+				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
+				newOverBottom;
+
+			// element is taller than within
+			if ( data.collisionHeight > outerHeight ) {
+				// element is initially over the top of within
+				if ( overTop > 0 && overBottom <= 0 ) {
+					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
+					position.top += overTop - newOverBottom;
+				// element is initially over bottom of within
+				} else if ( overBottom > 0 && overTop <= 0 ) {
+					position.top = withinOffset;
+				// element is initially over both top and bottom of within
+				} else {
+					if ( overTop > overBottom ) {
+						position.top = withinOffset + outerHeight - data.collisionHeight;
+					} else {
+						position.top = withinOffset;
+					}
+				}
+			// too far up -> align with top
+			} else if ( overTop > 0 ) {
+				position.top += overTop;
+			// too far down -> align with bottom edge
+			} else if ( overBottom > 0 ) {
+				position.top -= overBottom;
+			// adjust based on position and margin
+			} else {
+				position.top = max( position.top - collisionPosTop, position.top );
+			}
+		}
+	},
+	flip: {
+		left: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.offset.left + within.scrollLeft,
+				outerWidth = within.width,
+				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
+				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+				overLeft = collisionPosLeft - offsetLeft,
+				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
+				myOffset = data.my[ 0 ] === "left" ?
+					-data.elemWidth :
+					data.my[ 0 ] === "right" ?
+						data.elemWidth :
+						0,
+				atOffset = data.at[ 0 ] === "left" ?
+					data.targetWidth :
+					data.at[ 0 ] === "right" ?
+						-data.targetWidth :
+						0,
+				offset = -2 * data.offset[ 0 ],
+				newOverRight,
+				newOverLeft;
+
+			if ( overLeft < 0 ) {
+				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
+				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
+					position.left += myOffset + atOffset + offset;
+				}
+			} else if ( overRight > 0 ) {
+				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
+				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
+					position.left += myOffset + atOffset + offset;
+				}
+			}
+		},
+		top: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.offset.top + within.scrollTop,
+				outerHeight = within.height,
+				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
+				collisionPosTop = position.top - data.collisionPosition.marginTop,
+				overTop = collisionPosTop - offsetTop,
+				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
+				top = data.my[ 1 ] === "top",
+				myOffset = top ?
+					-data.elemHeight :
+					data.my[ 1 ] === "bottom" ?
+						data.elemHeight :
+						0,
+				atOffset = data.at[ 1 ] === "top" ?
+					data.targetHeight :
+					data.at[ 1 ] === "bottom" ?
+						-data.targetHeight :
+						0,
+				offset = -2 * data.offset[ 1 ],
+				newOverTop,
+				newOverBottom;
+			if ( overTop < 0 ) {
+				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
+				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
+					position.top += myOffset + atOffset + offset;
+				}
+			} else if ( overBottom > 0 ) {
+				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
+				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
+					position.top += myOffset + atOffset + offset;
+				}
+			}
+		}
+	},
+	flipfit: {
+		left: function() {
+			$.ui.position.flip.left.apply( this, arguments );
+			$.ui.position.fit.left.apply( this, arguments );
+		},
+		top: function() {
+			$.ui.position.flip.top.apply( this, arguments );
+			$.ui.position.fit.top.apply( this, arguments );
+		}
+	}
+};
+
+// fraction support test
+(function() {
+	var testElement, testElementParent, testElementStyle, offsetLeft, i,
+		body = document.getElementsByTagName( "body" )[ 0 ],
+		div = document.createElement( "div" );
+
+	//Create a "fake body" for testing based on method used in jQuery.support
+	testElement = document.createElement( body ? "div" : "body" );
+	testElementStyle = {
+		visibility: "hidden",
+		width: 0,
+		height: 0,
+		border: 0,
+		margin: 0,
+		background: "none"
+	};
+	if ( body ) {
+		$.extend( testElementStyle, {
+			position: "absolute",
+			left: "-1000px",
+			top: "-1000px"
+		});
+	}
+	for ( i in testElementStyle ) {
+		testElement.style[ i ] = testElementStyle[ i ];
+	}
+	testElement.appendChild( div );
+	testElementParent = body || document.documentElement;
+	testElementParent.insertBefore( testElement, testElementParent.firstChild );
+
+	div.style.cssText = "position: absolute; left: 10.7432222px;";
+
+	offsetLeft = $( div ).offset().left;
+	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
+
+	testElement.innerHTML = "";
+	testElementParent.removeChild( testElement );
+})();
+
+})();
+
+return $.ui.position;
+
+}));


[02/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
index 736aa68..7f117e9 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
@@ -19,6 +19,7 @@
 package org.apache.ambari.view.pig.test;
 
 import org.apache.ambari.view.pig.BasePigTest;
+import org.apache.ambari.view.pig.resources.jobs.JobResourceManager;
 import org.apache.ambari.view.pig.resources.jobs.JobService;
 import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
 import org.apache.ambari.view.pig.templeton.client.TempletonApi;
@@ -38,6 +39,7 @@ import javax.ws.rs.core.UriInfo;
 import java.io.*;
 import java.net.URI;
 import java.util.HashMap;
+import java.util.List;
 
 import static org.easymock.EasyMock.*;
 
@@ -45,6 +47,16 @@ public class JobTest extends BasePigTest {
   private JobService jobService;
   @Rule public ExpectedException thrown = ExpectedException.none();
 
+  @BeforeClass
+  public static void startUp() throws Exception {
+    BasePigTest.startUp(); // super
+  }
+
+  @AfterClass
+  public static void shutDown() throws Exception {
+    BasePigTest.shutDown(); // super
+  }
+
   @Override
   @Before
   public void setUp() throws Exception {
@@ -57,20 +69,21 @@ public class JobTest extends BasePigTest {
   public void tearDown() throws Exception {
     super.tearDown();
     jobService.getResourceManager().setTempletonApi(null);
-    JobService.setHdfsApi(null);
+    HdfsApi.dropAllConnections();
   }
 
-  private Response doCreateJob(String title, String pigScript, String templetonArguments) {
-    return doCreateJob(title, pigScript, templetonArguments, null);
+  public static Response doCreateJob(String title, String pigScript, String templetonArguments, JobService jobService) {
+    return doCreateJob(title, pigScript, templetonArguments, null, null, jobService);
   }
 
-  private Response doCreateJob(String title, String pigScript, String templetonArguments, String forcedContent) {
+  public static Response doCreateJob(String title, String pigScript, String templetonArguments, String forcedContent, String scriptId, JobService jobService) {
     JobService.PigJobRequest request = new JobService.PigJobRequest();
     request.job = new PigJob();
     request.job.setTitle(title);
     request.job.setPigScript(pigScript);
     request.job.setTempletonArguments(templetonArguments);
     request.job.setForcedContent(forcedContent);
+    request.job.setScriptId(scriptId);
 
     UriInfo uriInfo = createNiceMock(UriInfo.class);
     URI uri = UriBuilder.fromUri("http://host/a/b").build();
@@ -94,7 +107,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -102,7 +115,7 @@ public class JobTest extends BasePigTest {
     expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
     replay(api);
 
-    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
 
     Assert.assertEquals("-useHCatalog", do_stream.toString());
     Assert.assertEquals(201, response.getStatus());
@@ -111,14 +124,54 @@ public class JobTest extends BasePigTest {
     Assert.assertTrue(obj.containsKey("job"));
     Assert.assertNotNull(((PigJob) obj.get("job")).getId());
     Assert.assertFalse(((PigJob) obj.get("job")).getId().isEmpty());
-    Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/ambari-qa/test"));
+    Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/test"));
 
     PigJob job = ((PigJob) obj.get("job"));
-    Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_SUBMITTED, job.getStatus());
     Assert.assertTrue(job.isInProgress());
   }
 
   @Test
+  public void testListJobs() throws Exception {
+    HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+    expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true).anyTimes();
+
+    ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+    FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+    expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream).anyTimes();
+    replay(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
+
+    TempletonApi api = createNiceMock(TempletonApi.class);
+    jobService.getResourceManager().setTempletonApi(api);
+    TempletonApi.JobData data = api.new JobData();
+    expect(api.runPigQuery((File) anyObject(), anyString(), (String) isNull())).andReturn(data).anyTimes();
+    replay(api);
+
+    Response response = doCreateJob("Test", "/tmp/script.pig", null, null, "x42", jobService);
+    Assert.assertEquals(201, response.getStatus());
+
+    response = doCreateJob("Test", "/tmp/script.pig", null, null, "x42", jobService);
+    Assert.assertEquals(201, response.getStatus());
+
+    response = doCreateJob("Test", "/tmp/script.pig", null, null, "100", jobService);
+    Assert.assertEquals(201, response.getStatus());
+
+    response = jobService.getJobList("x42");
+    Assert.assertEquals(200, response.getStatus());
+    JSONObject obj = (JSONObject)response.getEntity();
+    Assert.assertTrue(obj.containsKey("jobs"));
+    Assert.assertEquals(2, ((List) obj.get("jobs")).size());
+
+    response = jobService.getJobList(null);
+    Assert.assertEquals(200, response.getStatus());
+    obj = (JSONObject)response.getEntity();
+    Assert.assertTrue(obj.containsKey("jobs"));
+    Assert.assertTrue(((List) obj.get("jobs")).size() > 2);
+  }
+
+  @Test
   public void testSubmitJobUsernameProvided() throws Exception {
     HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
     expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
@@ -128,7 +181,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -137,10 +190,10 @@ public class JobTest extends BasePigTest {
     replay(api);
 
     properties.put("dataworker.username", "luke");
-    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
     JSONObject obj = (JSONObject)response.getEntity();
     Assert.assertTrue(obj.containsKey("job"));
-    Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/luke/test"));
+    Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/test"));
   }
 
   @Test
@@ -153,7 +206,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -161,7 +214,7 @@ public class JobTest extends BasePigTest {
     expect(api.runPigQuery((File) anyObject(), anyString(), (String) isNull())).andReturn(data);
     replay(api);
 
-    Response response = doCreateJob("Test", "/tmp/script.pig", null);
+    Response response = doCreateJob("Test", "/tmp/script.pig", null, jobService);
 
     Assert.assertEquals("", do_stream.toString());
     Assert.assertEquals(201, response.getStatus());
@@ -170,10 +223,10 @@ public class JobTest extends BasePigTest {
     Assert.assertTrue(obj.containsKey("job"));
     Assert.assertNotNull(((PigJob) obj.get("job")).getId());
     Assert.assertFalse(((PigJob) obj.get("job")).getId().isEmpty());
-    Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/ambari-qa/test"));
+    Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/test"));
 
     PigJob job = ((PigJob) obj.get("job"));
-    Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_SUBMITTED, job.getStatus());
     Assert.assertTrue(job.isInProgress());
   }
 
@@ -187,7 +240,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -196,7 +249,7 @@ public class JobTest extends BasePigTest {
     replay(api);
 
     thrown.expect(ServiceFormattedException.class);
-    doCreateJob("Test", null, "-useHCatalog");
+    doCreateJob("Test", null, "-useHCatalog", jobService);
   }
 
   @Test
@@ -211,7 +264,7 @@ public class JobTest extends BasePigTest {
     expect(hdfsApi.create(endsWith("script.pig"), eq(true))).andReturn(scriptStream);
     expect(hdfsApi.create(endsWith("params"), eq(true))).andReturn(templetonArgsStream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -219,7 +272,7 @@ public class JobTest extends BasePigTest {
     expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
     replay(api);
 
-    Response response = doCreateJob("Test", null, "-useHCatalog", "pwd");  // with forcedContent
+    Response response = doCreateJob("Test", null, "-useHCatalog", "pwd", null, jobService);  // with forcedContent
     Assert.assertEquals(201, response.getStatus());
     Assert.assertEquals("-useHCatalog", baTempletonArgsStream.toString());
     Assert.assertEquals("pwd", baScriptStream.toString());
@@ -235,7 +288,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -244,7 +297,7 @@ public class JobTest extends BasePigTest {
     replay(api);
 
     thrown.expect(BadRequestFormattedException.class);
-    doCreateJob(null, "/tmp/1.pig", "-useHCatalog");
+    doCreateJob(null, "/tmp/1.pig", "-useHCatalog", jobService);
   }
 
   @Test
@@ -257,7 +310,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -266,7 +319,7 @@ public class JobTest extends BasePigTest {
     replay(api);
 
     thrown.expect(ServiceFormattedException.class);
-    doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+    doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
   }
 
   @Test
@@ -279,7 +332,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -289,11 +342,11 @@ public class JobTest extends BasePigTest {
     replay(api);
 
     thrown.expect(ServiceFormattedException.class);
-    doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+    doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
   }
 
   @Test
-  public void testKillJob() throws Exception {
+  public void testKillJobNoRemove() throws Exception {
     HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
     expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
 
@@ -302,7 +355,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createStrictMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -311,16 +364,55 @@ public class JobTest extends BasePigTest {
     expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
     replay(api);
 
-    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
     Assert.assertEquals(201, response.getStatus());
 
     reset(api);
     api.killJob(eq("job_id_##"));
+    expect(api.checkJob(anyString())).andReturn(api.new JobInfo()).anyTimes();
     replay(api);
     JSONObject obj = (JSONObject)response.getEntity();
     PigJob job = ((PigJob)obj.get("job"));
-    response = jobService.killJob(job.getId());
+    response = jobService.killJob(job.getId(), null);
     Assert.assertEquals(204, response.getStatus());
+
+    response = jobService.getJob(job.getId());  // it should still be present in DB
+    Assert.assertEquals(200, response.getStatus());
+  }
+
+  @Test
+  public void testKillJobWithRemove() throws Exception {
+    HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+    expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+    ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+    FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+    expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+    replay(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
+
+    TempletonApi api = createStrictMock(TempletonApi.class);
+    jobService.getResourceManager().setTempletonApi(api);
+    TempletonApi.JobData data = api.new JobData();
+    data.id = "job_id_##";
+    expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+    replay(api);
+
+    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
+    Assert.assertEquals(201, response.getStatus());
+
+    reset(api);
+    api.killJob(eq("job_id_##"));
+    expect(api.checkJob(anyString())).andReturn(api.new JobInfo()).anyTimes();
+    replay(api);
+    JSONObject obj = (JSONObject)response.getEntity();
+    PigJob job = ((PigJob)obj.get("job"));
+    response = jobService.killJob(job.getId(), "true");
+    Assert.assertEquals(204, response.getStatus());
+
+    thrown.expect(NotFoundFormattedException.class); // it should not be present in DB
+    jobService.getJob(job.getId());
   }
 
   @Test
@@ -333,7 +425,7 @@ public class JobTest extends BasePigTest {
     FSDataOutputStream stream = new FSDataOutputStream(do_stream);
     expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
     replay(hdfsApi);
-    JobService.setHdfsApi(hdfsApi);
+    HdfsApi.setInstance(context, hdfsApi);
 
     TempletonApi api = createNiceMock(TempletonApi.class);
     jobService.getResourceManager().setTempletonApi(api);
@@ -342,13 +434,13 @@ public class JobTest extends BasePigTest {
     expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
     replay(api);
 
-    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+    Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog", jobService);
 
     Assert.assertEquals("-useHCatalog", do_stream.toString());
     Assert.assertEquals(201, response.getStatus());
 
     PigJob job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_SUBMITTED, job.getStatus());
     Assert.assertTrue(job.isInProgress());
 
     // Retrieve status:
@@ -360,20 +452,20 @@ public class JobTest extends BasePigTest {
     response = jobService.getJob(job.getId());
     Assert.assertEquals(200, response.getStatus());
     job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_SUBMITTED, job.getStatus());
 
     // RUNNING
     reset(api);
     info = api.new JobInfo();
     info.status = new HashMap<String, Object>();
-    info.status.put("runState", (double)PigJob.RUN_STATE_RUNNING);
+    info.status.put("runState", (double) JobResourceManager.RUN_STATE_RUNNING);
     info.percentComplete = "30% complete";
     expect(api.checkJob(eq("job_id_#"))).andReturn(info);
     replay(api);
     response = jobService.getJob(job.getId());
     Assert.assertEquals(200, response.getStatus());
     job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.RUNNING, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_RUNNING, job.getStatus());
     Assert.assertTrue(job.isInProgress());
     Assert.assertEquals(30, (Object) job.getPercentComplete());
 
@@ -381,13 +473,13 @@ public class JobTest extends BasePigTest {
     reset(api);
     info = api.new JobInfo();
     info.status = new HashMap<String, Object>();
-    info.status.put("runState", (double)PigJob.RUN_STATE_SUCCEEDED);
+    info.status.put("runState", (double) JobResourceManager.RUN_STATE_SUCCEEDED);
     expect(api.checkJob(eq("job_id_#"))).andReturn(info);
     replay(api);
     response = jobService.getJob(job.getId());
     Assert.assertEquals(200, response.getStatus());
     job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.COMPLETED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_COMPLETED, job.getStatus());
     Assert.assertFalse(job.isInProgress());
     Assert.assertNull(job.getPercentComplete());
 
@@ -395,38 +487,38 @@ public class JobTest extends BasePigTest {
     reset(api);
     info = api.new JobInfo();
     info.status = new HashMap<String, Object>();
-    info.status.put("runState", (double)PigJob.RUN_STATE_PREP);
+    info.status.put("runState", (double) JobResourceManager.RUN_STATE_PREP);
     expect(api.checkJob(eq("job_id_#"))).andReturn(info);
     replay(api);
     response = jobService.getJob(job.getId());
     Assert.assertEquals(200, response.getStatus());
     job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.RUNNING, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_RUNNING, job.getStatus());
 
     // FAILED
     reset(api);
     info = api.new JobInfo();
     info.status = new HashMap<String, Object>();
-    info.status.put("runState", (double)PigJob.RUN_STATE_FAILED);
+    info.status.put("runState", (double) JobResourceManager.RUN_STATE_FAILED);
     expect(api.checkJob(eq("job_id_#"))).andReturn(info);
     replay(api);
     response = jobService.getJob(job.getId());
     Assert.assertEquals(200, response.getStatus());
     job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.FAILED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_FAILED, job.getStatus());
     Assert.assertFalse(job.isInProgress());
 
     // KILLED
     reset(api);
     info = api.new JobInfo();
     info.status = new HashMap<String, Object>();
-    info.status.put("runState", (double)PigJob.RUN_STATE_KILLED);
+    info.status.put("runState", (double) JobResourceManager.RUN_STATE_KILLED);
     expect(api.checkJob(eq("job_id_#"))).andReturn(info);
     replay(api);
     response = jobService.getJob(job.getId());
     Assert.assertEquals(200, response.getStatus());
     job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
-    Assert.assertEquals(PigJob.Status.KILLED, job.getStatus());
+    Assert.assertEquals(PigJob.PIG_JOB_STATE_KILLED, job.getStatus());
     Assert.assertFalse(job.isInProgress());
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
index 2bf3152..87e7d6b 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
@@ -23,6 +23,7 @@ import org.apache.ambari.view.pig.resources.files.FileService;
 import org.apache.ambari.view.pig.resources.scripts.ScriptService;
 import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
 import org.apache.ambari.view.pig.utils.BadRequestFormattedException;
+import org.apache.ambari.view.pig.utils.HdfsApi;
 import org.apache.ambari.view.pig.utils.NotFoundFormattedException;
 import org.json.simple.JSONObject;
 import org.junit.*;
@@ -40,140 +41,140 @@ import java.util.Map;
 import static org.easymock.EasyMock.*;
 
 public class ScriptTest extends HDFSTest {
-    private ScriptService scriptService;
-    @Rule public ExpectedException thrown = ExpectedException.none();
-
-    @BeforeClass
-    public static void startUp() throws Exception {
-        HDFSTest.startUp(); // super
-    }
-
-    @AfterClass
-    public static void shutDown() throws Exception {
-        HDFSTest.shutDown(); // super
-        FileService.setHdfsApi(null); //cleanup API connection
-    }
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        scriptService = getService(ScriptService.class, handler, context);
-    }
-
-    @Override
-    protected void setupProperties(Map<String, String> properties, File baseDir) throws Exception {
-        super.setupProperties(properties, baseDir);
-        properties.put("dataworker.scripts.path", "/tmp/.pigscripts");
-    }
-
-    private Response doCreateScript() {
-        return doCreateScript("Luke", "/tmp/luke.pig", scriptService);
-    }
-
-    public static Response doCreateScript(String title, String path, ScriptService scriptService) {
-        ScriptService.PigScriptRequest request = new ScriptService.PigScriptRequest();
-        request.script = new PigScript();
-        request.script.setTitle(title);
-        request.script.setPigScript(path);
-
-        UriInfo uriInfo = createNiceMock(UriInfo.class);
-        URI uri = UriBuilder.fromUri("http://host/a/b").build();
-        expect(uriInfo.getAbsolutePath()).andReturn(uri);
-
-        HttpServletResponse resp_obj = createNiceMock(HttpServletResponse.class);
-
-        resp_obj.setHeader(eq("Location"), anyString());
-
-        replay(uriInfo, resp_obj);
-        return scriptService.saveScript(request, resp_obj, uriInfo);
-    }
-
-    private Response doCreateScript(String title, String path) {
-        return doCreateScript(title, path, scriptService);
-    }
-
-    @Test
-    public void createScript() {
-        Response response = doCreateScript();
-        Assert.assertEquals(201, response.getStatus());
-
-        JSONObject obj = (JSONObject)response.getEntity();
-        Assert.assertTrue(obj.containsKey("script"));
-        Assert.assertNotNull(((PigScript) obj.get("script")).getId());
-        Assert.assertFalse(((PigScript) obj.get("script")).getId().isEmpty());
-    }
-
-    @Test
-    public void createScriptAutoCreate() {
-        Response response = doCreateScript("Test", null);
-        Assert.assertEquals(201, response.getStatus());
-
-        JSONObject obj = (JSONObject)response.getEntity();
-        Assert.assertTrue(obj.containsKey("script"));
-        Assert.assertNotNull(((PigScript) obj.get("script")).getId());
-        Assert.assertFalse(((PigScript) obj.get("script")).getId().isEmpty());
-        Assert.assertFalse(((PigScript) obj.get("script")).getPigScript().isEmpty());
-    }
-
-    @Test
-    public void scriptNotFound() {
-      thrown.expect(NotFoundFormattedException.class);
-      scriptService.getScript("4242");
-    }
-
-    @Test
-    public void updateScript() {
-        Response createdScript = doCreateScript();
-        String createdScriptId = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getId();
-
-        ScriptService.PigScriptRequest request = new ScriptService.PigScriptRequest();
-        request.script = new PigScript();
-        request.script.setTitle("Updated Script");
-
-        Response response = scriptService.updateScript(request, createdScriptId);
-        Assert.assertEquals(204, response.getStatus());
-
-        Response response2 = scriptService.getScript(createdScriptId);
-        Assert.assertEquals(200, response2.getStatus());
-
-        JSONObject obj = ((JSONObject) response2.getEntity());
-        Assert.assertTrue(obj.containsKey("script"));
-        Assert.assertEquals(((PigScript) obj.get("script")).getTitle(), request.script.getTitle());
-    }
-
-    @Test
-    public void deleteScript() {
-        Response createdScript = doCreateScript();
-        String createdScriptId = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getId();
-
-        Response response = scriptService.deleteScript(createdScriptId);
-        Assert.assertEquals(204, response.getStatus());
-
-        thrown.expect(NotFoundFormattedException.class);
-        scriptService.getScript(createdScriptId);
-    }
-
-    @Test
-    public void listScripts() {
-        Response createdScript1 = doCreateScript("Title 1", "/path/to/file.pig");
-        Response createdScript2 = doCreateScript("Title 2", "/path/to/file.pig");
-        String createdScriptId = ((PigScript) ((JSONObject) createdScript1.getEntity()).get("script")).getId();
-
-        Response response = scriptService.getScriptList();
-        Assert.assertEquals(200, response.getStatus());
-
-        JSONObject obj = (JSONObject) response.getEntity();
-        Assert.assertTrue(obj.containsKey("scripts"));
-        List<PigScript> scripts = (List<PigScript>) obj.get("scripts");
-        boolean containsTitle = false;
-        for(PigScript script : scripts)
-            containsTitle = containsTitle || script.getTitle().compareTo("Title 1") == 0;
-        Assert.assertTrue(containsTitle);
-
-        containsTitle = false;
-        for(PigScript script : scripts)
-            containsTitle = containsTitle || script.getTitle().compareTo("Title 2") == 0;
-        Assert.assertTrue(containsTitle);
-    }
+  private ScriptService scriptService;
+  @Rule public ExpectedException thrown = ExpectedException.none();
+
+  @BeforeClass
+  public static void startUp() throws Exception {
+      HDFSTest.startUp(); // super
+  }
+
+  @AfterClass
+  public static void shutDown() throws Exception {
+    HDFSTest.shutDown(); // super
+    HdfsApi.dropAllConnections(); //cleanup API connection
+  }
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    scriptService = getService(ScriptService.class, handler, context);
+  }
+
+  @Override
+  protected void setupProperties(Map<String, String> properties, File baseDir) throws Exception {
+    super.setupProperties(properties, baseDir);
+    properties.put("scripts.dir", "/tmp/.pigscripts");
+  }
+
+  private Response doCreateScript() {
+      return doCreateScript("Luke", "/tmp/luke.pig", scriptService);
+  }
+
+  public static Response doCreateScript(String title, String path, ScriptService scriptService) {
+    ScriptService.PigScriptRequest request = new ScriptService.PigScriptRequest();
+    request.script = new PigScript();
+    request.script.setTitle(title);
+    request.script.setPigScript(path);
+
+    UriInfo uriInfo = createNiceMock(UriInfo.class);
+    URI uri = UriBuilder.fromUri("http://host/a/b").build();
+    expect(uriInfo.getAbsolutePath()).andReturn(uri);
+
+    HttpServletResponse resp_obj = createNiceMock(HttpServletResponse.class);
+
+    resp_obj.setHeader(eq("Location"), anyString());
+
+    replay(uriInfo, resp_obj);
+    return scriptService.saveScript(request, resp_obj, uriInfo);
+  }
+
+  private Response doCreateScript(String title, String path) {
+      return doCreateScript(title, path, scriptService);
+  }
+
+  @Test
+  public void createScript() {
+    Response response = doCreateScript();
+    Assert.assertEquals(201, response.getStatus());
+
+    JSONObject obj = (JSONObject)response.getEntity();
+    Assert.assertTrue(obj.containsKey("script"));
+    Assert.assertNotNull(((PigScript) obj.get("script")).getId());
+    Assert.assertFalse(((PigScript) obj.get("script")).getId().isEmpty());
+  }
+
+  @Test
+  public void createScriptAutoCreate() {
+    Response response = doCreateScript("Test", null);
+    Assert.assertEquals(201, response.getStatus());
+
+    JSONObject obj = (JSONObject)response.getEntity();
+    Assert.assertTrue(obj.containsKey("script"));
+    Assert.assertNotNull(((PigScript) obj.get("script")).getId());
+    Assert.assertFalse(((PigScript) obj.get("script")).getId().isEmpty());
+    Assert.assertFalse(((PigScript) obj.get("script")).getPigScript().isEmpty());
+  }
+
+  @Test
+  public void scriptNotFound() {
+    thrown.expect(NotFoundFormattedException.class);
+    scriptService.getScript("4242");
+  }
+
+  @Test
+  public void updateScript() {
+    Response createdScript = doCreateScript();
+    String createdScriptId = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getId();
+
+    ScriptService.PigScriptRequest request = new ScriptService.PigScriptRequest();
+    request.script = new PigScript();
+    request.script.setTitle("Updated Script");
+
+    Response response = scriptService.updateScript(request, createdScriptId);
+    Assert.assertEquals(204, response.getStatus());
+
+    Response response2 = scriptService.getScript(createdScriptId);
+    Assert.assertEquals(200, response2.getStatus());
+
+    JSONObject obj = ((JSONObject) response2.getEntity());
+    Assert.assertTrue(obj.containsKey("script"));
+    Assert.assertEquals(((PigScript) obj.get("script")).getTitle(), request.script.getTitle());
+  }
+
+  @Test
+  public void deleteScript() {
+    Response createdScript = doCreateScript();
+    String createdScriptId = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getId();
+
+    Response response = scriptService.deleteScript(createdScriptId);
+    Assert.assertEquals(204, response.getStatus());
+
+    thrown.expect(NotFoundFormattedException.class);
+    scriptService.getScript(createdScriptId);
+  }
+
+  @Test
+  public void listScripts() {
+    Response createdScript1 = doCreateScript("Title 1", "/path/to/file.pig");
+    Response createdScript2 = doCreateScript("Title 2", "/path/to/file.pig");
+    String createdScriptId = ((PigScript) ((JSONObject) createdScript1.getEntity()).get("script")).getId();
+
+    Response response = scriptService.getScriptList();
+    Assert.assertEquals(200, response.getStatus());
+
+    JSONObject obj = (JSONObject) response.getEntity();
+    Assert.assertTrue(obj.containsKey("scripts"));
+    List<PigScript> scripts = (List<PigScript>) obj.get("scripts");
+    boolean containsTitle = false;
+    for(PigScript script : scripts)
+        containsTitle = containsTitle || script.getTitle().compareTo("Title 1") == 0;
+    Assert.assertTrue(containsTitle);
+
+    containsTitle = false;
+    for(PigScript script : scripts)
+        containsTitle = containsTitle || script.getTitle().compareTo("Title 2") == 0;
+    Assert.assertTrue(containsTitle);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
index 5b88d98..2db4f18 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
@@ -22,6 +22,7 @@ package org.apache.ambari.view.pig.test;
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.ViewResourceHandler;
 import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.persistence.DataStoreStorage;
 import org.apache.ambari.view.pig.persistence.InstanceKeyValueStorage;
 import org.apache.ambari.view.pig.persistence.Storage;
 import org.apache.ambari.view.pig.resources.files.FileService;
@@ -29,6 +30,7 @@ import org.apache.ambari.view.pig.resources.scripts.ScriptService;
 import org.apache.ambari.view.pig.persistence.utils.StorageUtil;
 import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
 import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.ambari.view.pig.utils.HdfsApi;
 import org.apache.ambari.view.pig.utils.MisconfigurationFormattedException;
 import org.apache.ambari.view.pig.utils.NotFoundFormattedException;
 import org.json.simple.JSONObject;
@@ -56,7 +58,7 @@ public class ScriptTestHDFSUnmanaged extends HDFSTest {
   @AfterClass
   public static void shutDown() throws Exception {
     HDFSTest.shutDown(); // super
-    FileService.setHdfsApi(null); //cleanup API connection
+    HdfsApi.dropAllConnections();
   }
 
   @Override
@@ -64,8 +66,8 @@ public class ScriptTestHDFSUnmanaged extends HDFSTest {
   public void setUp() throws Exception {
     handler = createNiceMock(ViewResourceHandler.class);
     context = createNiceMock(ViewContext.class);
-    FileService.setHdfsApi(null); //cleanup API connection
-    StorageUtil.setStorage(null);
+    HdfsApi.dropAllConnections();
+    StorageUtil.dropAllConnections();
   }
 
   @Test
@@ -77,8 +79,8 @@ public class ScriptTestHDFSUnmanaged extends HDFSTest {
         .getAbsoluteFile();
 
     properties.put("dataworker.storagePath", pigStorageFile.toString());
-//        properties.put("dataworker.scripts.path", "/tmp/.pigscripts");
-    properties.put("dataworker.defaultFs", hdfsURI);
+//        properties.put("scripts.dir", "/tmp/.pigscripts");
+    properties.put("webhdfs.url", hdfsURI);
 
     expect(context.getProperties()).andReturn(properties).anyTimes();
     expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
@@ -99,8 +101,8 @@ public class ScriptTestHDFSUnmanaged extends HDFSTest {
         .getAbsoluteFile();
 
     properties.put("dataworker.storagePath", pigStorageFile.toString());
-    properties.put("dataworker.scripts.path", "/tmp/.pigscripts");
-    properties.put("dataworker.defaultFs", hdfsURI);
+    properties.put("scripts.dir", "/tmp/.pigscripts");
+    properties.put("webhdfs.url", hdfsURI);
 
     expect(context.getProperties()).andReturn(properties).anyTimes();
     expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
@@ -110,12 +112,12 @@ public class ScriptTestHDFSUnmanaged extends HDFSTest {
 
     Response createdScript = doCreateScript("Test", null);
     String createdScriptPath = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getPigScript();
-    Assert.assertTrue(createdScriptPath.startsWith("/tmp/.pigscripts/ambari-qa/"));
+    Assert.assertTrue(createdScriptPath.startsWith("/tmp/.pigscripts/"));
 
     properties.put("dataworker.username", "luke");
     Response createdScript2 = doCreateScript("Test", null);
     String createdScriptPath2 = ((PigScript) ((JSONObject) createdScript2.getEntity()).get("script")).getPigScript();
-    Assert.assertTrue(createdScriptPath2.startsWith("/tmp/.pigscripts/luke/"));
+    Assert.assertTrue(createdScriptPath2.startsWith("/tmp/.pigscripts/"));
   }
 
   @Test
@@ -127,34 +129,34 @@ public class ScriptTestHDFSUnmanaged extends HDFSTest {
         .getAbsoluteFile();
 
 //        properties.put("dataworker.storagePath", pigStorageFile.toString());
-    properties.put("dataworker.scripts.path", "/tmp/.pigscripts");
-    properties.put("dataworker.defaultFs", hdfsURI);
+    properties.put("scripts.dir", "/tmp/.pigscripts");
+    properties.put("webhdfs.url", hdfsURI);
 
     expect(context.getProperties()).andReturn(properties).anyTimes();
     expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
 
     replay(handler, context);
 
-    Storage storage = StorageUtil.getStorage(context);
-    Assert.assertEquals(InstanceKeyValueStorage.class.getSimpleName(), storage.getClass().getSimpleName());
+    Storage storage = StorageUtil.getInstance(context).getStorage();
+    Assert.assertEquals(DataStoreStorage.class.getSimpleName(), storage.getClass().getSimpleName());
   }
 
   @Test
   public void hdfsApiNoUsernameProvided() throws IOException, InterruptedException {
     Map<String, String> properties = new HashMap<String, String>();
-    properties.put("dataworker.defaultFs", hdfsURI);
+    properties.put("webhdfs.url", hdfsURI);
 
     expect(context.getProperties()).andReturn(properties).anyTimes();
     expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
 
     replay(context);
 
-    // no dataworker.hdfs.username property
-    Assert.assertEquals("ambari-qa", BaseService.getHdfsUsername(context));
+    // no webhdfs.username property
+    Assert.assertEquals("ambari-qa", HdfsApi.getHdfsUsername(context));
 
-    // with dataworker.hdfs.username property
-    properties.put("dataworker.hdfs.username", "luke");
-    Assert.assertEquals("luke", BaseService.getHdfsUsername(context));
+    // with webhdfs.username property
+    properties.put("webhdfs.username", "luke");
+    Assert.assertEquals("luke", HdfsApi.getHdfsUsername(context));
   }
 
   private Response doCreateScript(String title, String path) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
index e61ac19..b4af66c 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
@@ -23,6 +23,7 @@ import org.apache.ambari.view.ViewResourceHandler;
 import org.apache.ambari.view.pig.BasePigTest;
 import org.apache.ambari.view.pig.resources.files.FileService;
 import org.apache.ambari.view.pig.resources.scripts.ScriptService;
+import org.apache.ambari.view.pig.utils.HdfsApi;
 import org.apache.ambari.view.pig.utils.MisconfigurationFormattedException;
 import org.junit.*;
 import org.junit.rules.ExpectedException;
@@ -45,7 +46,7 @@ public class ScriptTestUnmanaged extends BasePigTest {
 
   @AfterClass
   public static void shutDown() throws Exception {
-    FileService.setHdfsApi(null); //cleanup API connection
+    HdfsApi.dropAllConnections(); //cleanup API connection
   }
 
   @Before
@@ -67,7 +68,7 @@ public class ScriptTestUnmanaged extends BasePigTest {
   public void createScriptAutoCreateNoDefaultFS() {
     Map<String, String> properties = new HashMap<String, String>();
     properties.put("dataworker.storagePath", pigStorageFile.toString());
-    properties.put("dataworker.scripts.path", "/tmp/.pigscripts");
+    properties.put("scripts.dir", "/tmp/.pigscripts");
 
     expect(context.getProperties()).andReturn(properties).anyTimes();
     expect(context.getUsername()).andReturn("ambari-qa").anyTimes();


[03/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/resizable.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/resizable.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/resizable.js
new file mode 100644
index 0000000..82a15e5
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/resizable.js
@@ -0,0 +1,1179 @@
+/*!
+ * jQuery UI Resizable 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/resizable/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define([
+			"jquery",
+			"./core",
+			"./mouse",
+			"./widget"
+		], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+$.widget("ui.resizable", $.ui.mouse, {
+	version: "1.11.2",
+	widgetEventPrefix: "resize",
+	options: {
+		alsoResize: false,
+		animate: false,
+		animateDuration: "slow",
+		animateEasing: "swing",
+		aspectRatio: false,
+		autoHide: false,
+		containment: false,
+		ghost: false,
+		grid: false,
+		handles: "e,s,se",
+		helper: false,
+		maxHeight: null,
+		maxWidth: null,
+		minHeight: 10,
+		minWidth: 10,
+		// See #7960
+		zIndex: 90,
+
+		// callbacks
+		resize: null,
+		start: null,
+		stop: null
+	},
+
+	_num: function( value ) {
+		return parseInt( value, 10 ) || 0;
+	},
+
+	_isNumber: function( value ) {
+		return !isNaN( parseInt( value, 10 ) );
+	},
+
+	_hasScroll: function( el, a ) {
+
+		if ( $( el ).css( "overflow" ) === "hidden") {
+			return false;
+		}
+
+		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+			has = false;
+
+		if ( el[ scroll ] > 0 ) {
+			return true;
+		}
+
+		// TODO: determine which cases actually cause this to happen
+		// if the element doesn't have the scroll set, see if it's possible to
+		// set the scroll
+		el[ scroll ] = 1;
+		has = ( el[ scroll ] > 0 );
+		el[ scroll ] = 0;
+		return has;
+	},
+
+	_create: function() {
+
+		var n, i, handle, axis, hname,
+			that = this,
+			o = this.options;
+		this.element.addClass("ui-resizable");
+
+		$.extend(this, {
+			_aspectRatio: !!(o.aspectRatio),
+			aspectRatio: o.aspectRatio,
+			originalElement: this.element,
+			_proportionallyResizeElements: [],
+			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
+		});
+
+		// Wrap the element if it cannot hold child nodes
+		if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+			this.element.wrap(
+				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
+					position: this.element.css("position"),
+					width: this.element.outerWidth(),
+					height: this.element.outerHeight(),
+					top: this.element.css("top"),
+					left: this.element.css("left")
+				})
+			);
+
+			this.element = this.element.parent().data(
+				"ui-resizable", this.element.resizable( "instance" )
+			);
+
+			this.elementIsWrapper = true;
+
+			this.element.css({
+				marginLeft: this.originalElement.css("marginLeft"),
+				marginTop: this.originalElement.css("marginTop"),
+				marginRight: this.originalElement.css("marginRight"),
+				marginBottom: this.originalElement.css("marginBottom")
+			});
+			this.originalElement.css({
+				marginLeft: 0,
+				marginTop: 0,
+				marginRight: 0,
+				marginBottom: 0
+			});
+			// support: Safari
+			// Prevent Safari textarea resize
+			this.originalResizeStyle = this.originalElement.css("resize");
+			this.originalElement.css("resize", "none");
+
+			this._proportionallyResizeElements.push( this.originalElement.css({
+				position: "static",
+				zoom: 1,
+				display: "block"
+			}) );
+
+			// support: IE9
+			// avoid IE jump (hard set the margin)
+			this.originalElement.css({ margin: this.originalElement.css("margin") });
+
+			this._proportionallyResize();
+		}
+
+		this.handles = o.handles ||
+			( !$(".ui-resizable-handle", this.element).length ?
+				"e,s,se" : {
+					n: ".ui-resizable-n",
+					e: ".ui-resizable-e",
+					s: ".ui-resizable-s",
+					w: ".ui-resizable-w",
+					se: ".ui-resizable-se",
+					sw: ".ui-resizable-sw",
+					ne: ".ui-resizable-ne",
+					nw: ".ui-resizable-nw"
+				} );
+
+		if (this.handles.constructor === String) {
+
+			if ( this.handles === "all") {
+				this.handles = "n,e,s,w,se,sw,ne,nw";
+			}
+
+			n = this.handles.split(",");
+			this.handles = {};
+
+			for (i = 0; i < n.length; i++) {
+
+				handle = $.trim(n[i]);
+				hname = "ui-resizable-" + handle;
+				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
+
+				axis.css({ zIndex: o.zIndex });
+
+				// TODO : What's going on here?
+				if ("se" === handle) {
+					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
+				}
+
+				this.handles[handle] = ".ui-resizable-" + handle;
+				this.element.append(axis);
+			}
+
+		}
+
+		this._renderAxis = function(target) {
+
+			var i, axis, padPos, padWrapper;
+
+			target = target || this.element;
+
+			for (i in this.handles) {
+
+				if (this.handles[i].constructor === String) {
+					this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
+				}
+
+				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+					axis = $(this.handles[i], this.element);
+
+					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+					padPos = [ "padding",
+						/ne|nw|n/.test(i) ? "Top" :
+						/se|sw|s/.test(i) ? "Bottom" :
+						/^e$/.test(i) ? "Right" : "Left" ].join("");
+
+					target.css(padPos, padWrapper);
+
+					this._proportionallyResize();
+
+				}
+
+				// TODO: What's that good for? There's not anything to be executed left
+				if (!$(this.handles[i]).length) {
+					continue;
+				}
+			}
+		};
+
+		// TODO: make renderAxis a prototype function
+		this._renderAxis(this.element);
+
+		this._handles = $(".ui-resizable-handle", this.element)
+			.disableSelection();
+
+		this._handles.mouseover(function() {
+			if (!that.resizing) {
+				if (this.className) {
+					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+				}
+				that.axis = axis && axis[1] ? axis[1] : "se";
+			}
+		});
+
+		if (o.autoHide) {
+			this._handles.hide();
+			$(this.element)
+				.addClass("ui-resizable-autohide")
+				.mouseenter(function() {
+					if (o.disabled) {
+						return;
+					}
+					$(this).removeClass("ui-resizable-autohide");
+					that._handles.show();
+				})
+				.mouseleave(function() {
+					if (o.disabled) {
+						return;
+					}
+					if (!that.resizing) {
+						$(this).addClass("ui-resizable-autohide");
+						that._handles.hide();
+					}
+				});
+		}
+
+		this._mouseInit();
+
+	},
+
+	_destroy: function() {
+
+		this._mouseDestroy();
+
+		var wrapper,
+			_destroy = function(exp) {
+				$(exp)
+					.removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+					.removeData("resizable")
+					.removeData("ui-resizable")
+					.unbind(".resizable")
+					.find(".ui-resizable-handle")
+						.remove();
+			};
+
+		// TODO: Unwrap at same DOM position
+		if (this.elementIsWrapper) {
+			_destroy(this.element);
+			wrapper = this.element;
+			this.originalElement.css({
+				position: wrapper.css("position"),
+				width: wrapper.outerWidth(),
+				height: wrapper.outerHeight(),
+				top: wrapper.css("top"),
+				left: wrapper.css("left")
+			}).insertAfter( wrapper );
+			wrapper.remove();
+		}
+
+		this.originalElement.css("resize", this.originalResizeStyle);
+		_destroy(this.originalElement);
+
+		return this;
+	},
+
+	_mouseCapture: function(event) {
+		var i, handle,
+			capture = false;
+
+		for (i in this.handles) {
+			handle = $(this.handles[i])[0];
+			if (handle === event.target || $.contains(handle, event.target)) {
+				capture = true;
+			}
+		}
+
+		return !this.options.disabled && capture;
+	},
+
+	_mouseStart: function(event) {
+
+		var curleft, curtop, cursor,
+			o = this.options,
+			el = this.element;
+
+		this.resizing = true;
+
+		this._renderProxy();
+
+		curleft = this._num(this.helper.css("left"));
+		curtop = this._num(this.helper.css("top"));
+
+		if (o.containment) {
+			curleft += $(o.containment).scrollLeft() || 0;
+			curtop += $(o.containment).scrollTop() || 0;
+		}
+
+		this.offset = this.helper.offset();
+		this.position = { left: curleft, top: curtop };
+
+		this.size = this._helper ? {
+				width: this.helper.width(),
+				height: this.helper.height()
+			} : {
+				width: el.width(),
+				height: el.height()
+			};
+
+		this.originalSize = this._helper ? {
+				width: el.outerWidth(),
+				height: el.outerHeight()
+			} : {
+				width: el.width(),
+				height: el.height()
+			};
+
+		this.sizeDiff = {
+			width: el.outerWidth() - el.width(),
+			height: el.outerHeight() - el.height()
+		};
+
+		this.originalPosition = { left: curleft, top: curtop };
+		this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+		this.aspectRatio = (typeof o.aspectRatio === "number") ?
+			o.aspectRatio :
+			((this.originalSize.width / this.originalSize.height) || 1);
+
+		cursor = $(".ui-resizable-" + this.axis).css("cursor");
+		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
+
+		el.addClass("ui-resizable-resizing");
+		this._propagate("start", event);
+		return true;
+	},
+
+	_mouseDrag: function(event) {
+
+		var data, props,
+			smp = this.originalMousePosition,
+			a = this.axis,
+			dx = (event.pageX - smp.left) || 0,
+			dy = (event.pageY - smp.top) || 0,
+			trigger = this._change[a];
+
+		this._updatePrevProperties();
+
+		if (!trigger) {
+			return false;
+		}
+
+		data = trigger.apply(this, [ event, dx, dy ]);
+
+		this._updateVirtualBoundaries(event.shiftKey);
+		if (this._aspectRatio || event.shiftKey) {
+			data = this._updateRatio(data, event);
+		}
+
+		data = this._respectSize(data, event);
+
+		this._updateCache(data);
+
+		this._propagate("resize", event);
+
+		props = this._applyChanges();
+
+		if ( !this._helper && this._proportionallyResizeElements.length ) {
+			this._proportionallyResize();
+		}
+
+		if ( !$.isEmptyObject( props ) ) {
+			this._updatePrevProperties();
+			this._trigger( "resize", event, this.ui() );
+			this._applyChanges();
+		}
+
+		return false;
+	},
+
+	_mouseStop: function(event) {
+
+		this.resizing = false;
+		var pr, ista, soffseth, soffsetw, s, left, top,
+			o = this.options, that = this;
+
+		if (this._helper) {
+
+			pr = this._proportionallyResizeElements;
+			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
+			soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
+			soffsetw = ista ? 0 : that.sizeDiff.width;
+
+			s = {
+				width: (that.helper.width()  - soffsetw),
+				height: (that.helper.height() - soffseth)
+			};
+			left = (parseInt(that.element.css("left"), 10) +
+				(that.position.left - that.originalPosition.left)) || null;
+			top = (parseInt(that.element.css("top"), 10) +
+				(that.position.top - that.originalPosition.top)) || null;
+
+			if (!o.animate) {
+				this.element.css($.extend(s, { top: top, left: left }));
+			}
+
+			that.helper.height(that.size.height);
+			that.helper.width(that.size.width);
+
+			if (this._helper && !o.animate) {
+				this._proportionallyResize();
+			}
+		}
+
+		$("body").css("cursor", "auto");
+
+		this.element.removeClass("ui-resizable-resizing");
+
+		this._propagate("stop", event);
+
+		if (this._helper) {
+			this.helper.remove();
+		}
+
+		return false;
+
+	},
+
+	_updatePrevProperties: function() {
+		this.prevPosition = {
+			top: this.position.top,
+			left: this.position.left
+		};
+		this.prevSize = {
+			width: this.size.width,
+			height: this.size.height
+		};
+	},
+
+	_applyChanges: function() {
+		var props = {};
+
+		if ( this.position.top !== this.prevPosition.top ) {
+			props.top = this.position.top + "px";
+		}
+		if ( this.position.left !== this.prevPosition.left ) {
+			props.left = this.position.left + "px";
+		}
+		if ( this.size.width !== this.prevSize.width ) {
+			props.width = this.size.width + "px";
+		}
+		if ( this.size.height !== this.prevSize.height ) {
+			props.height = this.size.height + "px";
+		}
+
+		this.helper.css( props );
+
+		return props;
+	},
+
+	_updateVirtualBoundaries: function(forceAspectRatio) {
+		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
+			o = this.options;
+
+		b = {
+			minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
+			maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
+			minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
+			maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
+		};
+
+		if (this._aspectRatio || forceAspectRatio) {
+			pMinWidth = b.minHeight * this.aspectRatio;
+			pMinHeight = b.minWidth / this.aspectRatio;
+			pMaxWidth = b.maxHeight * this.aspectRatio;
+			pMaxHeight = b.maxWidth / this.aspectRatio;
+
+			if (pMinWidth > b.minWidth) {
+				b.minWidth = pMinWidth;
+			}
+			if (pMinHeight > b.minHeight) {
+				b.minHeight = pMinHeight;
+			}
+			if (pMaxWidth < b.maxWidth) {
+				b.maxWidth = pMaxWidth;
+			}
+			if (pMaxHeight < b.maxHeight) {
+				b.maxHeight = pMaxHeight;
+			}
+		}
+		this._vBoundaries = b;
+	},
+
+	_updateCache: function(data) {
+		this.offset = this.helper.offset();
+		if (this._isNumber(data.left)) {
+			this.position.left = data.left;
+		}
+		if (this._isNumber(data.top)) {
+			this.position.top = data.top;
+		}
+		if (this._isNumber(data.height)) {
+			this.size.height = data.height;
+		}
+		if (this._isNumber(data.width)) {
+			this.size.width = data.width;
+		}
+	},
+
+	_updateRatio: function( data ) {
+
+		var cpos = this.position,
+			csize = this.size,
+			a = this.axis;
+
+		if (this._isNumber(data.height)) {
+			data.width = (data.height * this.aspectRatio);
+		} else if (this._isNumber(data.width)) {
+			data.height = (data.width / this.aspectRatio);
+		}
+
+		if (a === "sw") {
+			data.left = cpos.left + (csize.width - data.width);
+			data.top = null;
+		}
+		if (a === "nw") {
+			data.top = cpos.top + (csize.height - data.height);
+			data.left = cpos.left + (csize.width - data.width);
+		}
+
+		return data;
+	},
+
+	_respectSize: function( data ) {
+
+		var o = this._vBoundaries,
+			a = this.axis,
+			ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
+			ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+			isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
+			isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
+			dw = this.originalPosition.left + this.originalSize.width,
+			dh = this.position.top + this.size.height,
+			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+		if (isminw) {
+			data.width = o.minWidth;
+		}
+		if (isminh) {
+			data.height = o.minHeight;
+		}
+		if (ismaxw) {
+			data.width = o.maxWidth;
+		}
+		if (ismaxh) {
+			data.height = o.maxHeight;
+		}
+
+		if (isminw && cw) {
+			data.left = dw - o.minWidth;
+		}
+		if (ismaxw && cw) {
+			data.left = dw - o.maxWidth;
+		}
+		if (isminh && ch) {
+			data.top = dh - o.minHeight;
+		}
+		if (ismaxh && ch) {
+			data.top = dh - o.maxHeight;
+		}
+
+		// Fixing jump error on top/left - bug #2330
+		if (!data.width && !data.height && !data.left && data.top) {
+			data.top = null;
+		} else if (!data.width && !data.height && !data.top && data.left) {
+			data.left = null;
+		}
+
+		return data;
+	},
+
+	_getPaddingPlusBorderDimensions: function( element ) {
+		var i = 0,
+			widths = [],
+			borders = [
+				element.css( "borderTopWidth" ),
+				element.css( "borderRightWidth" ),
+				element.css( "borderBottomWidth" ),
+				element.css( "borderLeftWidth" )
+			],
+			paddings = [
+				element.css( "paddingTop" ),
+				element.css( "paddingRight" ),
+				element.css( "paddingBottom" ),
+				element.css( "paddingLeft" )
+			];
+
+		for ( ; i < 4; i++ ) {
+			widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
+			widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
+		}
+
+		return {
+			height: widths[ 0 ] + widths[ 2 ],
+			width: widths[ 1 ] + widths[ 3 ]
+		};
+	},
+
+	_proportionallyResize: function() {
+
+		if (!this._proportionallyResizeElements.length) {
+			return;
+		}
+
+		var prel,
+			i = 0,
+			element = this.helper || this.element;
+
+		for ( ; i < this._proportionallyResizeElements.length; i++) {
+
+			prel = this._proportionallyResizeElements[i];
+
+			// TODO: Seems like a bug to cache this.outerDimensions
+			// considering that we are in a loop.
+			if (!this.outerDimensions) {
+				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
+			}
+
+			prel.css({
+				height: (element.height() - this.outerDimensions.height) || 0,
+				width: (element.width() - this.outerDimensions.width) || 0
+			});
+
+		}
+
+	},
+
+	_renderProxy: function() {
+
+		var el = this.element, o = this.options;
+		this.elementOffset = el.offset();
+
+		if (this._helper) {
+
+			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
+
+			this.helper.addClass(this._helper).css({
+				width: this.element.outerWidth() - 1,
+				height: this.element.outerHeight() - 1,
+				position: "absolute",
+				left: this.elementOffset.left + "px",
+				top: this.elementOffset.top + "px",
+				zIndex: ++o.zIndex //TODO: Don't modify option
+			});
+
+			this.helper
+				.appendTo("body")
+				.disableSelection();
+
+		} else {
+			this.helper = this.element;
+		}
+
+	},
+
+	_change: {
+		e: function(event, dx) {
+			return { width: this.originalSize.width + dx };
+		},
+		w: function(event, dx) {
+			var cs = this.originalSize, sp = this.originalPosition;
+			return { left: sp.left + dx, width: cs.width - dx };
+		},
+		n: function(event, dx, dy) {
+			var cs = this.originalSize, sp = this.originalPosition;
+			return { top: sp.top + dy, height: cs.height - dy };
+		},
+		s: function(event, dx, dy) {
+			return { height: this.originalSize.height + dy };
+		},
+		se: function(event, dx, dy) {
+			return $.extend(this._change.s.apply(this, arguments),
+				this._change.e.apply(this, [ event, dx, dy ]));
+		},
+		sw: function(event, dx, dy) {
+			return $.extend(this._change.s.apply(this, arguments),
+				this._change.w.apply(this, [ event, dx, dy ]));
+		},
+		ne: function(event, dx, dy) {
+			return $.extend(this._change.n.apply(this, arguments),
+				this._change.e.apply(this, [ event, dx, dy ]));
+		},
+		nw: function(event, dx, dy) {
+			return $.extend(this._change.n.apply(this, arguments),
+				this._change.w.apply(this, [ event, dx, dy ]));
+		}
+	},
+
+	_propagate: function(n, event) {
+		$.ui.plugin.call(this, n, [ event, this.ui() ]);
+		(n !== "resize" && this._trigger(n, event, this.ui()));
+	},
+
+	plugins: {},
+
+	ui: function() {
+		return {
+			originalElement: this.originalElement,
+			element: this.element,
+			helper: this.helper,
+			position: this.position,
+			size: this.size,
+			originalSize: this.originalSize,
+			originalPosition: this.originalPosition
+		};
+	}
+
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "animate", {
+
+	stop: function( event ) {
+		var that = $(this).resizable( "instance" ),
+			o = that.options,
+			pr = that._proportionallyResizeElements,
+			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+			soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
+			soffsetw = ista ? 0 : that.sizeDiff.width,
+			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
+			left = (parseInt(that.element.css("left"), 10) +
+				(that.position.left - that.originalPosition.left)) || null,
+			top = (parseInt(that.element.css("top"), 10) +
+				(that.position.top - that.originalPosition.top)) || null;
+
+		that.element.animate(
+			$.extend(style, top && left ? { top: top, left: left } : {}), {
+				duration: o.animateDuration,
+				easing: o.animateEasing,
+				step: function() {
+
+					var data = {
+						width: parseInt(that.element.css("width"), 10),
+						height: parseInt(that.element.css("height"), 10),
+						top: parseInt(that.element.css("top"), 10),
+						left: parseInt(that.element.css("left"), 10)
+					};
+
+					if (pr && pr.length) {
+						$(pr[0]).css({ width: data.width, height: data.height });
+					}
+
+					// propagating resize, and updating values for each animation step
+					that._updateCache(data);
+					that._propagate("resize", event);
+
+				}
+			}
+		);
+	}
+
+});
+
+$.ui.plugin.add( "resizable", "containment", {
+
+	start: function() {
+		var element, p, co, ch, cw, width, height,
+			that = $( this ).resizable( "instance" ),
+			o = that.options,
+			el = that.element,
+			oc = o.containment,
+			ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
+
+		if ( !ce ) {
+			return;
+		}
+
+		that.containerElement = $( ce );
+
+		if ( /document/.test( oc ) || oc === document ) {
+			that.containerOffset = {
+				left: 0,
+				top: 0
+			};
+			that.containerPosition = {
+				left: 0,
+				top: 0
+			};
+
+			that.parentData = {
+				element: $( document ),
+				left: 0,
+				top: 0,
+				width: $( document ).width(),
+				height: $( document ).height() || document.body.parentNode.scrollHeight
+			};
+		} else {
+			element = $( ce );
+			p = [];
+			$([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
+				p[ i ] = that._num( element.css( "padding" + name ) );
+			});
+
+			that.containerOffset = element.offset();
+			that.containerPosition = element.position();
+			that.containerSize = {
+				height: ( element.innerHeight() - p[ 3 ] ),
+				width: ( element.innerWidth() - p[ 1 ] )
+			};
+
+			co = that.containerOffset;
+			ch = that.containerSize.height;
+			cw = that.containerSize.width;
+			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
+			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
+
+			that.parentData = {
+				element: ce,
+				left: co.left,
+				top: co.top,
+				width: width,
+				height: height
+			};
+		}
+	},
+
+	resize: function( event ) {
+		var woset, hoset, isParent, isOffsetRelative,
+			that = $( this ).resizable( "instance" ),
+			o = that.options,
+			co = that.containerOffset,
+			cp = that.position,
+			pRatio = that._aspectRatio || event.shiftKey,
+			cop = {
+				top: 0,
+				left: 0
+			},
+			ce = that.containerElement,
+			continueResize = true;
+
+		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
+			cop = co;
+		}
+
+		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
+			that.size.width = that.size.width +
+				( that._helper ?
+					( that.position.left - co.left ) :
+					( that.position.left - cop.left ) );
+
+			if ( pRatio ) {
+				that.size.height = that.size.width / that.aspectRatio;
+				continueResize = false;
+			}
+			that.position.left = o.helper ? co.left : 0;
+		}
+
+		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
+			that.size.height = that.size.height +
+				( that._helper ?
+					( that.position.top - co.top ) :
+					that.position.top );
+
+			if ( pRatio ) {
+				that.size.width = that.size.height * that.aspectRatio;
+				continueResize = false;
+			}
+			that.position.top = that._helper ? co.top : 0;
+		}
+
+		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
+		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
+
+		if ( isParent && isOffsetRelative ) {
+			that.offset.left = that.parentData.left + that.position.left;
+			that.offset.top = that.parentData.top + that.position.top;
+		} else {
+			that.offset.left = that.element.offset().left;
+			that.offset.top = that.element.offset().top;
+		}
+
+		woset = Math.abs( that.sizeDiff.width +
+			(that._helper ?
+				that.offset.left - cop.left :
+				(that.offset.left - co.left)) );
+
+		hoset = Math.abs( that.sizeDiff.height +
+			(that._helper ?
+				that.offset.top - cop.top :
+				(that.offset.top - co.top)) );
+
+		if ( woset + that.size.width >= that.parentData.width ) {
+			that.size.width = that.parentData.width - woset;
+			if ( pRatio ) {
+				that.size.height = that.size.width / that.aspectRatio;
+				continueResize = false;
+			}
+		}
+
+		if ( hoset + that.size.height >= that.parentData.height ) {
+			that.size.height = that.parentData.height - hoset;
+			if ( pRatio ) {
+				that.size.width = that.size.height * that.aspectRatio;
+				continueResize = false;
+			}
+		}
+
+		if ( !continueResize ){
+			that.position.left = that.prevPosition.left;
+			that.position.top = that.prevPosition.top;
+			that.size.width = that.prevSize.width;
+			that.size.height = that.prevSize.height;
+		}
+	},
+
+	stop: function() {
+		var that = $( this ).resizable( "instance" ),
+			o = that.options,
+			co = that.containerOffset,
+			cop = that.containerPosition,
+			ce = that.containerElement,
+			helper = $( that.helper ),
+			ho = helper.offset(),
+			w = helper.outerWidth() - that.sizeDiff.width,
+			h = helper.outerHeight() - that.sizeDiff.height;
+
+		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
+			$( this ).css({
+				left: ho.left - cop.left - co.left,
+				width: w,
+				height: h
+			});
+		}
+
+		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
+			$( this ).css({
+				left: ho.left - cop.left - co.left,
+				width: w,
+				height: h
+			});
+		}
+	}
+});
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+	start: function() {
+		var that = $(this).resizable( "instance" ),
+			o = that.options,
+			_store = function(exp) {
+				$(exp).each(function() {
+					var el = $(this);
+					el.data("ui-resizable-alsoresize", {
+						width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+						left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
+					});
+				});
+			};
+
+		if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
+			if (o.alsoResize.length) {
+				o.alsoResize = o.alsoResize[0];
+				_store(o.alsoResize);
+			} else {
+				$.each(o.alsoResize, function(exp) {
+					_store(exp);
+				});
+			}
+		} else {
+			_store(o.alsoResize);
+		}
+	},
+
+	resize: function(event, ui) {
+		var that = $(this).resizable( "instance" ),
+			o = that.options,
+			os = that.originalSize,
+			op = that.originalPosition,
+			delta = {
+				height: (that.size.height - os.height) || 0,
+				width: (that.size.width - os.width) || 0,
+				top: (that.position.top - op.top) || 0,
+				left: (that.position.left - op.left) || 0
+			},
+
+			_alsoResize = function(exp, c) {
+				$(exp).each(function() {
+					var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
+						css = c && c.length ?
+							c :
+							el.parents(ui.originalElement[0]).length ?
+								[ "width", "height" ] :
+								[ "width", "height", "top", "left" ];
+
+					$.each(css, function(i, prop) {
+						var sum = (start[prop] || 0) + (delta[prop] || 0);
+						if (sum && sum >= 0) {
+							style[prop] = sum || null;
+						}
+					});
+
+					el.css(style);
+				});
+			};
+
+		if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
+			$.each(o.alsoResize, function(exp, c) {
+				_alsoResize(exp, c);
+			});
+		} else {
+			_alsoResize(o.alsoResize);
+		}
+	},
+
+	stop: function() {
+		$(this).removeData("resizable-alsoresize");
+	}
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+	start: function() {
+
+		var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
+
+		that.ghost = that.originalElement.clone();
+		that.ghost
+			.css({
+				opacity: 0.25,
+				display: "block",
+				position: "relative",
+				height: cs.height,
+				width: cs.width,
+				margin: 0,
+				left: 0,
+				top: 0
+			})
+			.addClass("ui-resizable-ghost")
+			.addClass(typeof o.ghost === "string" ? o.ghost : "");
+
+		that.ghost.appendTo(that.helper);
+
+	},
+
+	resize: function() {
+		var that = $(this).resizable( "instance" );
+		if (that.ghost) {
+			that.ghost.css({
+				position: "relative",
+				height: that.size.height,
+				width: that.size.width
+			});
+		}
+	},
+
+	stop: function() {
+		var that = $(this).resizable( "instance" );
+		if (that.ghost && that.helper) {
+			that.helper.get(0).removeChild(that.ghost.get(0));
+		}
+	}
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+	resize: function() {
+		var outerDimensions,
+			that = $(this).resizable( "instance" ),
+			o = that.options,
+			cs = that.size,
+			os = that.originalSize,
+			op = that.originalPosition,
+			a = that.axis,
+			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
+			gridX = (grid[0] || 1),
+			gridY = (grid[1] || 1),
+			ox = Math.round((cs.width - os.width) / gridX) * gridX,
+			oy = Math.round((cs.height - os.height) / gridY) * gridY,
+			newWidth = os.width + ox,
+			newHeight = os.height + oy,
+			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
+			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
+			isMinWidth = o.minWidth && (o.minWidth > newWidth),
+			isMinHeight = o.minHeight && (o.minHeight > newHeight);
+
+		o.grid = grid;
+
+		if (isMinWidth) {
+			newWidth += gridX;
+		}
+		if (isMinHeight) {
+			newHeight += gridY;
+		}
+		if (isMaxWidth) {
+			newWidth -= gridX;
+		}
+		if (isMaxHeight) {
+			newHeight -= gridY;
+		}
+
+		if (/^(se|s|e)$/.test(a)) {
+			that.size.width = newWidth;
+			that.size.height = newHeight;
+		} else if (/^(ne)$/.test(a)) {
+			that.size.width = newWidth;
+			that.size.height = newHeight;
+			that.position.top = op.top - oy;
+		} else if (/^(sw)$/.test(a)) {
+			that.size.width = newWidth;
+			that.size.height = newHeight;
+			that.position.left = op.left - ox;
+		} else {
+			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
+				outerDimensions = that._getPaddingPlusBorderDimensions( this );
+			}
+
+			if ( newHeight - gridY > 0 ) {
+				that.size.height = newHeight;
+				that.position.top = op.top - oy;
+			} else {
+				newHeight = gridY - outerDimensions.height;
+				that.size.height = newHeight;
+				that.position.top = op.top + os.height - newHeight;
+			}
+			if ( newWidth - gridX > 0 ) {
+				that.size.width = newWidth;
+				that.position.left = op.left - ox;
+			} else {
+				newWidth = gridY - outerDimensions.height;
+				that.size.width = newWidth;
+				that.position.left = op.left + os.width - newWidth;
+			}
+		}
+	}
+
+});
+
+return $.ui.resizable;
+
+}));

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/selectable.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/selectable.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/selectable.js
new file mode 100644
index 0000000..d3c4285
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/selectable.js
@@ -0,0 +1,287 @@
+/*!
+ * jQuery UI Selectable 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/selectable/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define([
+			"jquery",
+			"./core",
+			"./mouse",
+			"./widget"
+		], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+return $.widget("ui.selectable", $.ui.mouse, {
+	version: "1.11.2",
+	options: {
+		appendTo: "body",
+		autoRefresh: true,
+		distance: 0,
+		filter: "*",
+		tolerance: "touch",
+
+		// callbacks
+		selected: null,
+		selecting: null,
+		start: null,
+		stop: null,
+		unselected: null,
+		unselecting: null
+	},
+	_create: function() {
+		var selectees,
+			that = this;
+
+		this.element.addClass("ui-selectable");
+
+		this.dragged = false;
+
+		// cache selectee children based on filter
+		this.refresh = function() {
+			selectees = $(that.options.filter, that.element[0]);
+			selectees.addClass("ui-selectee");
+			selectees.each(function() {
+				var $this = $(this),
+					pos = $this.offset();
+				$.data(this, "selectable-item", {
+					element: this,
+					$element: $this,
+					left: pos.left,
+					top: pos.top,
+					right: pos.left + $this.outerWidth(),
+					bottom: pos.top + $this.outerHeight(),
+					startselected: false,
+					selected: $this.hasClass("ui-selected"),
+					selecting: $this.hasClass("ui-selecting"),
+					unselecting: $this.hasClass("ui-unselecting")
+				});
+			});
+		};
+		this.refresh();
+
+		this.selectees = selectees.addClass("ui-selectee");
+
+		this._mouseInit();
+
+		this.helper = $("<div class='ui-selectable-helper'></div>");
+	},
+
+	_destroy: function() {
+		this.selectees
+			.removeClass("ui-selectee")
+			.removeData("selectable-item");
+		this.element
+			.removeClass("ui-selectable ui-selectable-disabled");
+		this._mouseDestroy();
+	},
+
+	_mouseStart: function(event) {
+		var that = this,
+			options = this.options;
+
+		this.opos = [ event.pageX, event.pageY ];
+
+		if (this.options.disabled) {
+			return;
+		}
+
+		this.selectees = $(options.filter, this.element[0]);
+
+		this._trigger("start", event);
+
+		$(options.appendTo).append(this.helper);
+		// position helper (lasso)
+		this.helper.css({
+			"left": event.pageX,
+			"top": event.pageY,
+			"width": 0,
+			"height": 0
+		});
+
+		if (options.autoRefresh) {
+			this.refresh();
+		}
+
+		this.selectees.filter(".ui-selected").each(function() {
+			var selectee = $.data(this, "selectable-item");
+			selectee.startselected = true;
+			if (!event.metaKey && !event.ctrlKey) {
+				selectee.$element.removeClass("ui-selected");
+				selectee.selected = false;
+				selectee.$element.addClass("ui-unselecting");
+				selectee.unselecting = true;
+				// selectable UNSELECTING callback
+				that._trigger("unselecting", event, {
+					unselecting: selectee.element
+				});
+			}
+		});
+
+		$(event.target).parents().addBack().each(function() {
+			var doSelect,
+				selectee = $.data(this, "selectable-item");
+			if (selectee) {
+				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
+				selectee.$element
+					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+				selectee.unselecting = !doSelect;
+				selectee.selecting = doSelect;
+				selectee.selected = doSelect;
+				// selectable (UN)SELECTING callback
+				if (doSelect) {
+					that._trigger("selecting", event, {
+						selecting: selectee.element
+					});
+				} else {
+					that._trigger("unselecting", event, {
+						unselecting: selectee.element
+					});
+				}
+				return false;
+			}
+		});
+
+	},
+
+	_mouseDrag: function(event) {
+
+		this.dragged = true;
+
+		if (this.options.disabled) {
+			return;
+		}
+
+		var tmp,
+			that = this,
+			options = this.options,
+			x1 = this.opos[0],
+			y1 = this.opos[1],
+			x2 = event.pageX,
+			y2 = event.pageY;
+
+		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
+		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
+		this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
+
+		this.selectees.each(function() {
+			var selectee = $.data(this, "selectable-item"),
+				hit = false;
+
+			//prevent helper from being selected if appendTo: selectable
+			if (!selectee || selectee.element === that.element[0]) {
+				return;
+			}
+
+			if (options.tolerance === "touch") {
+				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+			} else if (options.tolerance === "fit") {
+				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+			}
+
+			if (hit) {
+				// SELECT
+				if (selectee.selected) {
+					selectee.$element.removeClass("ui-selected");
+					selectee.selected = false;
+				}
+				if (selectee.unselecting) {
+					selectee.$element.removeClass("ui-unselecting");
+					selectee.unselecting = false;
+				}
+				if (!selectee.selecting) {
+					selectee.$element.addClass("ui-selecting");
+					selectee.selecting = true;
+					// selectable SELECTING callback
+					that._trigger("selecting", event, {
+						selecting: selectee.element
+					});
+				}
+			} else {
+				// UNSELECT
+				if (selectee.selecting) {
+					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
+						selectee.$element.removeClass("ui-selecting");
+						selectee.selecting = false;
+						selectee.$element.addClass("ui-selected");
+						selectee.selected = true;
+					} else {
+						selectee.$element.removeClass("ui-selecting");
+						selectee.selecting = false;
+						if (selectee.startselected) {
+							selectee.$element.addClass("ui-unselecting");
+							selectee.unselecting = true;
+						}
+						// selectable UNSELECTING callback
+						that._trigger("unselecting", event, {
+							unselecting: selectee.element
+						});
+					}
+				}
+				if (selectee.selected) {
+					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
+						selectee.$element.removeClass("ui-selected");
+						selectee.selected = false;
+
+						selectee.$element.addClass("ui-unselecting");
+						selectee.unselecting = true;
+						// selectable UNSELECTING callback
+						that._trigger("unselecting", event, {
+							unselecting: selectee.element
+						});
+					}
+				}
+			}
+		});
+
+		return false;
+	},
+
+	_mouseStop: function(event) {
+		var that = this;
+
+		this.dragged = false;
+
+		$(".ui-unselecting", this.element[0]).each(function() {
+			var selectee = $.data(this, "selectable-item");
+			selectee.$element.removeClass("ui-unselecting");
+			selectee.unselecting = false;
+			selectee.startselected = false;
+			that._trigger("unselected", event, {
+				unselected: selectee.element
+			});
+		});
+		$(".ui-selecting", this.element[0]).each(function() {
+			var selectee = $.data(this, "selectable-item");
+			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
+			selectee.selecting = false;
+			selectee.selected = true;
+			selectee.startselected = true;
+			that._trigger("selected", event, {
+				selected: selectee.element
+			});
+		});
+		this._trigger("stop", event);
+
+		this.helper.remove();
+
+		return false;
+	}
+
+});
+
+}));

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/widget.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/widget.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/widget.js
new file mode 100644
index 0000000..c2fb788
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/widget.js
@@ -0,0 +1,557 @@
+/*!
+ * jQuery UI Widget 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/jQuery.widget/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define( [ "jquery" ], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+var widget_uuid = 0,
+	widget_slice = Array.prototype.slice;
+
+$.cleanData = (function( orig ) {
+	return function( elems ) {
+		var events, elem, i;
+		for ( i = 0; (elem = elems[i]) != null; i++ ) {
+			try {
+
+				// Only trigger remove when necessary to save time
+				events = $._data( elem, "events" );
+				if ( events && events.remove ) {
+					$( elem ).triggerHandler( "remove" );
+				}
+
+			// http://bugs.jquery.com/ticket/8235
+			} catch ( e ) {}
+		}
+		orig( elems );
+	};
+})( $.cleanData );
+
+$.widget = function( name, base, prototype ) {
+	var fullName, existingConstructor, constructor, basePrototype,
+		// proxiedPrototype allows the provided prototype to remain unmodified
+		// so that it can be used as a mixin for multiple widgets (#8876)
+		proxiedPrototype = {},
+		namespace = name.split( "." )[ 0 ];
+
+	name = name.split( "." )[ 1 ];
+	fullName = namespace + "-" + name;
+
+	if ( !prototype ) {
+		prototype = base;
+		base = $.Widget;
+	}
+
+	// create selector for plugin
+	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+		return !!$.data( elem, fullName );
+	};
+
+	$[ namespace ] = $[ namespace ] || {};
+	existingConstructor = $[ namespace ][ name ];
+	constructor = $[ namespace ][ name ] = function( options, element ) {
+		// allow instantiation without "new" keyword
+		if ( !this._createWidget ) {
+			return new constructor( options, element );
+		}
+
+		// allow instantiation without initializing for simple inheritance
+		// must use "new" keyword (the code above always passes args)
+		if ( arguments.length ) {
+			this._createWidget( options, element );
+		}
+	};
+	// extend with the existing constructor to carry over any static properties
+	$.extend( constructor, existingConstructor, {
+		version: prototype.version,
+		// copy the object used to create the prototype in case we need to
+		// redefine the widget later
+		_proto: $.extend( {}, prototype ),
+		// track widgets that inherit from this widget in case this widget is
+		// redefined after a widget inherits from it
+		_childConstructors: []
+	});
+
+	basePrototype = new base();
+	// we need to make the options hash a property directly on the new instance
+	// otherwise we'll modify the options hash on the prototype that we're
+	// inheriting from
+	basePrototype.options = $.widget.extend( {}, basePrototype.options );
+	$.each( prototype, function( prop, value ) {
+		if ( !$.isFunction( value ) ) {
+			proxiedPrototype[ prop ] = value;
+			return;
+		}
+		proxiedPrototype[ prop ] = (function() {
+			var _super = function() {
+					return base.prototype[ prop ].apply( this, arguments );
+				},
+				_superApply = function( args ) {
+					return base.prototype[ prop ].apply( this, args );
+				};
+			return function() {
+				var __super = this._super,
+					__superApply = this._superApply,
+					returnValue;
+
+				this._super = _super;
+				this._superApply = _superApply;
+
+				returnValue = value.apply( this, arguments );
+
+				this._super = __super;
+				this._superApply = __superApply;
+
+				return returnValue;
+			};
+		})();
+	});
+	constructor.prototype = $.widget.extend( basePrototype, {
+		// TODO: remove support for widgetEventPrefix
+		// always use the name + a colon as the prefix, e.g., draggable:start
+		// don't prefix for widgets that aren't DOM-based
+		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
+	}, proxiedPrototype, {
+		constructor: constructor,
+		namespace: namespace,
+		widgetName: name,
+		widgetFullName: fullName
+	});
+
+	// If this widget is being redefined then we need to find all widgets that
+	// are inheriting from it and redefine all of them so that they inherit from
+	// the new version of this widget. We're essentially trying to replace one
+	// level in the prototype chain.
+	if ( existingConstructor ) {
+		$.each( existingConstructor._childConstructors, function( i, child ) {
+			var childPrototype = child.prototype;
+
+			// redefine the child widget using the same prototype that was
+			// originally used, but inherit from the new version of the base
+			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+		});
+		// remove the list of existing child constructors from the old constructor
+		// so the old child constructors can be garbage collected
+		delete existingConstructor._childConstructors;
+	} else {
+		base._childConstructors.push( constructor );
+	}
+
+	$.widget.bridge( name, constructor );
+
+	return constructor;
+};
+
+$.widget.extend = function( target ) {
+	var input = widget_slice.call( arguments, 1 ),
+		inputIndex = 0,
+		inputLength = input.length,
+		key,
+		value;
+	for ( ; inputIndex < inputLength; inputIndex++ ) {
+		for ( key in input[ inputIndex ] ) {
+			value = input[ inputIndex ][ key ];
+			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+				// Clone objects
+				if ( $.isPlainObject( value ) ) {
+					target[ key ] = $.isPlainObject( target[ key ] ) ?
+						$.widget.extend( {}, target[ key ], value ) :
+						// Don't extend strings, arrays, etc. with objects
+						$.widget.extend( {}, value );
+				// Copy everything else by reference
+				} else {
+					target[ key ] = value;
+				}
+			}
+		}
+	}
+	return target;
+};
+
+$.widget.bridge = function( name, object ) {
+	var fullName = object.prototype.widgetFullName || name;
+	$.fn[ name ] = function( options ) {
+		var isMethodCall = typeof options === "string",
+			args = widget_slice.call( arguments, 1 ),
+			returnValue = this;
+
+		// allow multiple hashes to be passed on init
+		options = !isMethodCall && args.length ?
+			$.widget.extend.apply( null, [ options ].concat(args) ) :
+			options;
+
+		if ( isMethodCall ) {
+			this.each(function() {
+				var methodValue,
+					instance = $.data( this, fullName );
+				if ( options === "instance" ) {
+					returnValue = instance;
+					return false;
+				}
+				if ( !instance ) {
+					return $.error( "cannot call methods on " + name + " prior to initialization; " +
+						"attempted to call method '" + options + "'" );
+				}
+				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+				}
+				methodValue = instance[ options ].apply( instance, args );
+				if ( methodValue !== instance && methodValue !== undefined ) {
+					returnValue = methodValue && methodValue.jquery ?
+						returnValue.pushStack( methodValue.get() ) :
+						methodValue;
+					return false;
+				}
+			});
+		} else {
+			this.each(function() {
+				var instance = $.data( this, fullName );
+				if ( instance ) {
+					instance.option( options || {} );
+					if ( instance._init ) {
+						instance._init();
+					}
+				} else {
+					$.data( this, fullName, new object( options, this ) );
+				}
+			});
+		}
+
+		return returnValue;
+	};
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+	widgetName: "widget",
+	widgetEventPrefix: "",
+	defaultElement: "<div>",
+	options: {
+		disabled: false,
+
+		// callbacks
+		create: null
+	},
+	_createWidget: function( options, element ) {
+		element = $( element || this.defaultElement || this )[ 0 ];
+		this.element = $( element );
+		this.uuid = widget_uuid++;
+		this.eventNamespace = "." + this.widgetName + this.uuid;
+
+		this.bindings = $();
+		this.hoverable = $();
+		this.focusable = $();
+
+		if ( element !== this ) {
+			$.data( element, this.widgetFullName, this );
+			this._on( true, this.element, {
+				remove: function( event ) {
+					if ( event.target === element ) {
+						this.destroy();
+					}
+				}
+			});
+			this.document = $( element.style ?
+				// element within the document
+				element.ownerDocument :
+				// element is window or document
+				element.document || element );
+			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+		}
+
+		this.options = $.widget.extend( {},
+			this.options,
+			this._getCreateOptions(),
+			options );
+
+		this._create();
+		this._trigger( "create", null, this._getCreateEventData() );
+		this._init();
+	},
+	_getCreateOptions: $.noop,
+	_getCreateEventData: $.noop,
+	_create: $.noop,
+	_init: $.noop,
+
+	destroy: function() {
+		this._destroy();
+		// we can probably remove the unbind calls in 2.0
+		// all event bindings should go through this._on()
+		this.element
+			.unbind( this.eventNamespace )
+			.removeData( this.widgetFullName )
+			// support: jquery <1.6.3
+			// http://bugs.jquery.com/ticket/9413
+			.removeData( $.camelCase( this.widgetFullName ) );
+		this.widget()
+			.unbind( this.eventNamespace )
+			.removeAttr( "aria-disabled" )
+			.removeClass(
+				this.widgetFullName + "-disabled " +
+				"ui-state-disabled" );
+
+		// clean up events and states
+		this.bindings.unbind( this.eventNamespace );
+		this.hoverable.removeClass( "ui-state-hover" );
+		this.focusable.removeClass( "ui-state-focus" );
+	},
+	_destroy: $.noop,
+
+	widget: function() {
+		return this.element;
+	},
+
+	option: function( key, value ) {
+		var options = key,
+			parts,
+			curOption,
+			i;
+
+		if ( arguments.length === 0 ) {
+			// don't return a reference to the internal hash
+			return $.widget.extend( {}, this.options );
+		}
+
+		if ( typeof key === "string" ) {
+			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+			options = {};
+			parts = key.split( "." );
+			key = parts.shift();
+			if ( parts.length ) {
+				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+				for ( i = 0; i < parts.length - 1; i++ ) {
+					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+					curOption = curOption[ parts[ i ] ];
+				}
+				key = parts.pop();
+				if ( arguments.length === 1 ) {
+					return curOption[ key ] === undefined ? null : curOption[ key ];
+				}
+				curOption[ key ] = value;
+			} else {
+				if ( arguments.length === 1 ) {
+					return this.options[ key ] === undefined ? null : this.options[ key ];
+				}
+				options[ key ] = value;
+			}
+		}
+
+		this._setOptions( options );
+
+		return this;
+	},
+	_setOptions: function( options ) {
+		var key;
+
+		for ( key in options ) {
+			this._setOption( key, options[ key ] );
+		}
+
+		return this;
+	},
+	_setOption: function( key, value ) {
+		this.options[ key ] = value;
+
+		if ( key === "disabled" ) {
+			this.widget()
+				.toggleClass( this.widgetFullName + "-disabled", !!value );
+
+			// If the widget is becoming disabled, then nothing is interactive
+			if ( value ) {
+				this.hoverable.removeClass( "ui-state-hover" );
+				this.focusable.removeClass( "ui-state-focus" );
+			}
+		}
+
+		return this;
+	},
+
+	enable: function() {
+		return this._setOptions({ disabled: false });
+	},
+	disable: function() {
+		return this._setOptions({ disabled: true });
+	},
+
+	_on: function( suppressDisabledCheck, element, handlers ) {
+		var delegateElement,
+			instance = this;
+
+		// no suppressDisabledCheck flag, shuffle arguments
+		if ( typeof suppressDisabledCheck !== "boolean" ) {
+			handlers = element;
+			element = suppressDisabledCheck;
+			suppressDisabledCheck = false;
+		}
+
+		// no element argument, shuffle and use this.element
+		if ( !handlers ) {
+			handlers = element;
+			element = this.element;
+			delegateElement = this.widget();
+		} else {
+			element = delegateElement = $( element );
+			this.bindings = this.bindings.add( element );
+		}
+
+		$.each( handlers, function( event, handler ) {
+			function handlerProxy() {
+				// allow widgets to customize the disabled handling
+				// - disabled as an array instead of boolean
+				// - disabled class as method for disabling individual parts
+				if ( !suppressDisabledCheck &&
+						( instance.options.disabled === true ||
+							$( this ).hasClass( "ui-state-disabled" ) ) ) {
+					return;
+				}
+				return ( typeof handler === "string" ? instance[ handler ] : handler )
+					.apply( instance, arguments );
+			}
+
+			// copy the guid so direct unbinding works
+			if ( typeof handler !== "string" ) {
+				handlerProxy.guid = handler.guid =
+					handler.guid || handlerProxy.guid || $.guid++;
+			}
+
+			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
+				eventName = match[1] + instance.eventNamespace,
+				selector = match[2];
+			if ( selector ) {
+				delegateElement.delegate( selector, eventName, handlerProxy );
+			} else {
+				element.bind( eventName, handlerProxy );
+			}
+		});
+	},
+
+	_off: function( element, eventName ) {
+		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
+			this.eventNamespace;
+		element.unbind( eventName ).undelegate( eventName );
+
+		// Clear the stack to avoid memory leaks (#10056)
+		this.bindings = $( this.bindings.not( element ).get() );
+		this.focusable = $( this.focusable.not( element ).get() );
+		this.hoverable = $( this.hoverable.not( element ).get() );
+	},
+
+	_delay: function( handler, delay ) {
+		function handlerProxy() {
+			return ( typeof handler === "string" ? instance[ handler ] : handler )
+				.apply( instance, arguments );
+		}
+		var instance = this;
+		return setTimeout( handlerProxy, delay || 0 );
+	},
+
+	_hoverable: function( element ) {
+		this.hoverable = this.hoverable.add( element );
+		this._on( element, {
+			mouseenter: function( event ) {
+				$( event.currentTarget ).addClass( "ui-state-hover" );
+			},
+			mouseleave: function( event ) {
+				$( event.currentTarget ).removeClass( "ui-state-hover" );
+			}
+		});
+	},
+
+	_focusable: function( element ) {
+		this.focusable = this.focusable.add( element );
+		this._on( element, {
+			focusin: function( event ) {
+				$( event.currentTarget ).addClass( "ui-state-focus" );
+			},
+			focusout: function( event ) {
+				$( event.currentTarget ).removeClass( "ui-state-focus" );
+			}
+		});
+	},
+
+	_trigger: function( type, event, data ) {
+		var prop, orig,
+			callback = this.options[ type ];
+
+		data = data || {};
+		event = $.Event( event );
+		event.type = ( type === this.widgetEventPrefix ?
+			type :
+			this.widgetEventPrefix + type ).toLowerCase();
+		// the original event may come from any element
+		// so we need to reset the target on the new event
+		event.target = this.element[ 0 ];
+
+		// copy original event properties over to the new event
+		orig = event.originalEvent;
+		if ( orig ) {
+			for ( prop in orig ) {
+				if ( !( prop in event ) ) {
+					event[ prop ] = orig[ prop ];
+				}
+			}
+		}
+
+		this.element.trigger( event, data );
+		return !( $.isFunction( callback ) &&
+			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+			event.isDefaultPrevented() );
+	}
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+		if ( typeof options === "string" ) {
+			options = { effect: options };
+		}
+		var hasOptions,
+			effectName = !options ?
+				method :
+				options === true || typeof options === "number" ?
+					defaultEffect :
+					options.effect || defaultEffect;
+		options = options || {};
+		if ( typeof options === "number" ) {
+			options = { duration: options };
+		}
+		hasOptions = !$.isEmptyObject( options );
+		options.complete = callback;
+		if ( options.delay ) {
+			element.delay( options.delay );
+		}
+		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+			element[ method ]( options );
+		} else if ( effectName !== method && element[ effectName ] ) {
+			element[ effectName ]( options.duration, options.easing, callback );
+		} else {
+			element.queue(function( next ) {
+				$( this )[ method ]();
+				if ( callback ) {
+					callback.call( element[ 0 ] );
+				}
+				next();
+			});
+		}
+	};
+});
+
+return $.widget;
+
+}));

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/moment-duration-format.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/moment-duration-format.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/moment-duration-format.js
new file mode 100644
index 0000000..7283ecc
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/moment-duration-format.js
@@ -0,0 +1,482 @@
+/*! Moment Duration Format v1.3.0
+ *  https://github.com/jsmreese/moment-duration-format
+ *  Date: 2014-07-15
+ *
+ *  Duration format plugin function for the Moment.js library
+ *  http://momentjs.com/
+ *
+ *  Copyright 2014 John Madhavan-Reese
+ *  Released under the MIT license
+ */
+
+(function (root, undefined) {
+
+	// repeatZero(qty)
+	// returns "0" repeated qty times
+	function repeatZero(qty) {
+		var result = "";
+
+		// exit early
+		// if qty is 0 or a negative number
+		// or doesn't coerce to an integer
+		qty = parseInt(qty, 10);
+		if (!qty || qty < 1) { return result; }
+
+		while (qty) {
+			result += "0";
+			qty -= 1;
+		}
+
+		return result;
+	}
+
+	// padZero(str, len [, isRight])
+	// pads a string with zeros up to a specified length
+	// will not pad a string if its length is aready
+	// greater than or equal to the specified length
+	// default output pads with zeros on the left
+	// set isRight to `true` to pad with zeros on the right
+	function padZero(str, len, isRight) {
+		if (str == null) { str = ""; }
+		str = "" + str;
+
+		return (isRight ? str : "") + repeatZero(len - str.length) + (isRight ? "" : str);
+	}
+
+	// isArray
+	function isArray(array) {
+		return Object.prototype.toString.call(array) === "[object Array]";
+	}
+
+	// isObject
+	function isObject(obj) {
+		return Object.prototype.toString.call(obj) === "[object Object]";
+	}
+
+	// findLast
+	function findLast(array, callback) {
+		var index = array.length;
+
+		while (index -= 1) {
+			if (callback(array[index])) { return array[index]; }
+		}
+	}
+
+	// find
+	function find(array, callback) {
+		var index = 0,
+			max = array.length,
+			match;
+
+		if (typeof callback !== "function") {
+			match = callback;
+			callback = function (item) {
+				return item === match;
+			};
+		}
+
+		while (index < max) {
+			if (callback(array[index])) { return array[index]; }
+			index += 1;
+		}
+	}
+
+	// each
+	function each(array, callback) {
+		var index = 0,
+			max = array.length;
+
+		if (!array || !max) { return; }
+
+		while (index < max) {
+			if (callback(array[index], index) === false) { return; }
+			index += 1;
+		}
+	}
+
+	// map
+	function map(array, callback) {
+		var index = 0,
+			max = array.length,
+			ret = [];
+
+		if (!array || !max) { return ret; }
+
+		while (index < max) {
+			ret[index] = callback(array[index], index);
+			index += 1;
+		}
+
+		return ret;
+	}
+
+	// pluck
+	function pluck(array, prop) {
+		return map(array, function (item) {
+			return item[prop];
+		});
+	}
+
+	// compact
+	function compact(array) {
+		var ret = [];
+
+		each(array, function (item) {
+			if (item) { ret.push(item); }
+		});
+
+		return ret;
+	}
+
+	// unique
+	function unique(array) {
+		var ret = [];
+
+		each(array, function (_a) {
+			if (!find(ret, _a)) { ret.push(_a); }
+		});
+
+		return ret;
+	}
+
+	// intersection
+	function intersection(a, b) {
+		var ret = [];
+
+		each(a, function (_a) {
+			each(b, function (_b) {
+				if (_a === _b) { ret.push(_a); }
+			});
+		});
+
+		return unique(ret);
+	}
+
+	// rest
+	function rest(array, callback) {
+		var ret = [];
+
+		each(array, function (item, index) {
+			if (!callback(item)) {
+				ret = array.slice(index);
+				return false;
+			}
+		});
+
+		return ret;
+	}
+
+	// initial
+	function initial(array, callback) {
+		var reversed = array.slice().reverse();
+
+		return rest(reversed, callback).reverse();
+	}
+
+	// extend
+	function extend(a, b) {
+		for (var key in b) {
+			if (b.hasOwnProperty(key)) { a[key] = b[key]; }
+		}
+
+		return a;
+	}
+
+	// define internal moment reference
+	var moment;
+
+	if (typeof require === "function") {
+		try { moment = require('moment'); }
+		catch (e) {}
+	}
+
+	if (!moment && root.moment) {
+		moment = root.moment;
+	}
+
+	if (!moment) {
+		throw "Moment Duration Format cannot find Moment.js";
+	}
+
+	// moment.duration.format([template] [, precision] [, settings])
+	moment.duration.fn.format = function () {
+
+		var tokenizer, tokens, types, typeMap, momentTypes, foundFirst, trimIndex,
+			args = [].slice.call(arguments),
+			settings = extend({}, this.format.defaults),
+			// keep a shadow copy of this moment for calculating remainders
+			remainder = moment.duration(this);
+
+		// add a reference to this duration object to the settings for use
+		// in a template function
+		settings.duration = this;
+
+		// parse arguments
+		each(args, function (arg) {
+			if (typeof arg === "string" || typeof arg === "function") {
+				settings.template = arg;
+				return;
+			}
+
+			if (typeof arg === "number") {
+				settings.precision = arg;
+				return;
+			}
+
+			if (isObject(arg)) {
+				extend(settings, arg);
+			}
+		});
+
+		// types
+		types = settings.types = (isArray(settings.types) ? settings.types : settings.types.split(" "));
+
+		// template
+		if (typeof settings.template === "function") {
+			settings.template = settings.template.apply(settings);
+		}
+
+		// tokenizer regexp
+		tokenizer = new RegExp(map(types, function (type) {
+			return settings[type].source;
+		}).join("|"), "g");
+
+		// token type map function
+		typeMap = function (token) {
+			return find(types, function (type) {
+				return settings[type].test(token);
+			});
+		};
+
+		// tokens array
+		tokens = map(settings.template.match(tokenizer), function (token, index) {
+			var type = typeMap(token),
+				length = token.length;
+
+			return {
+				index: index,
+				length: length,
+
+				// replace escaped tokens with the non-escaped token text
+				token: (type === "escape" ? token.replace(settings.escape, "$1") : token),
+
+				// ignore type on non-moment tokens
+				type: ((type === "escape" || type === "general") ? null : type)
+
+				// calculate base value for all moment tokens
+				//baseValue: ((type === "escape" || type === "general") ? null : this.as(type))
+			};
+		}, this);
+
+		// unique moment token types in the template (in order of descending magnitude)
+		momentTypes = intersection(types, unique(compact(pluck(tokens, "type"))));
+
+		// exit early if there are no momentTypes
+		if (!momentTypes.length) {
+			return pluck(tokens, "token").join("");
+		}
+
+		// calculate values for each token type in the template
+		each(momentTypes, function (momentType, index) {
+			var value, wholeValue, decimalValue, isLeast, isMost;
+
+			// calculate integer and decimal value portions
+			value = remainder.as(momentType);
+			wholeValue = (value > 0 ? Math.floor(value) : Math.ceil(value));
+			decimalValue = value - wholeValue;
+
+			// is this the least-significant moment token found?
+			isLeast = ((index + 1) === momentTypes.length);
+
+			// is this the most-significant moment token found?
+			isMost = (!index);
+
+			// update tokens array
+			// using this algorithm to not assume anything about
+			// the order or frequency of any tokens
+			each(tokens, function (token) {
+				if (token.type === momentType) {
+					extend(token, {
+						value: value,
+						wholeValue: wholeValue,
+						decimalValue: decimalValue,
+						isLeast: isLeast,
+						isMost: isMost
+					});
+
+					if (isMost) {
+						// note the length of the most-significant moment token:
+						// if it is greater than one and forceLength is not set, default forceLength to `true`
+						if (settings.forceLength == null && token.length > 1) {
+							settings.forceLength = true;
+						}
+
+						// rationale is this:
+						// if the template is "h:mm:ss" and the moment value is 5 minutes, the user-friendly output is "5:00", not "05:00"
+						// shouldn't pad the `minutes` token even though it has length of two
+						// if the template is "hh:mm:ss", the user clearly wanted everything padded so we should output "05:00"
+						// if the user wanted the full padded output, they can set `{ trim: false }` to get "00:05:00"
+					}
+				}
+			});
+
+			// update remainder
+			remainder.subtract(wholeValue, momentType);
+		});
+
+		// trim tokens array
+		if (settings.trim) {
+			tokens = (settings.trim === "left" ? rest : initial)(tokens, function (token) {
+				// return `true` if:
+				// the token is not the least moment token (don't trim the least moment token)
+				// the token is a moment token that does not have a value (don't trim moment tokens that have a whole value)
+				return !(token.isLeast || (token.type != null && token.wholeValue));
+			});
+		}
+
+
+		// build output
+
+		// the first moment token can have special handling
+		foundFirst = false;
+
+		// run the map in reverse order if trimming from the right
+		if (settings.trim === "right") {
+			tokens.reverse();
+		}
+
+		tokens = map(tokens, function (token) {
+			var val,
+				decVal;
+
+			if (!token.type) {
+				// if it is not a moment token, use the token as its own value
+				return token.token;
+			}
+
+			// apply negative precision formatting to the least-significant moment token
+			if (token.isLeast && (settings.precision < 0)) {
+				val = (Math.floor(token.wholeValue * Math.pow(10, settings.precision)) * Math.pow(10, -settings.precision)).toString();
+			} else {
+				val = token.wholeValue.toString();
+			}
+
+			// remove negative sign from the beginning
+			val = val.replace(/^\-/, "");
+
+			// apply token length formatting
+			// special handling for the first moment token that is not the most significant in a trimmed template
+			if (token.length > 1 && (foundFirst || token.isMost || settings.forceLength)) {
+				val = padZero(val, token.length);
+			}
+
+			// add decimal value if precision > 0
+			if (token.isLeast && (settings.precision > 0)) {
+				decVal = token.decimalValue.toString().replace(/^\-/, "").split(/\.|e\-/);
+				switch (decVal.length) {
+					case 1:
+						val += "." + padZero(decVal[0], settings.precision, true).slice(0, settings.precision);
+						break;
+
+					case 2:
+						val += "." + padZero(decVal[1], settings.precision, true).slice(0, settings.precision);
+						break;
+
+					case 3:
+						val += "." + padZero(repeatZero((+decVal[2]) - 1) + (decVal[0] || "0") + decVal[1], settings.precision, true).slice(0, settings.precision);
+						break;
+
+					default:
+						throw "Moment Duration Format: unable to parse token decimal value.";
+				}
+			}
+
+			// add a negative sign if the value is negative and token is most significant
+			if (token.isMost && token.value < 0) {
+				val = "-" + val;
+			}
+
+			foundFirst = true;
+
+			return val;
+		});
+
+		// undo the reverse if trimming from the right
+		if (settings.trim === "right") {
+			tokens.reverse();
+		}
+
+		return tokens.join("");
+	};
+
+	moment.duration.fn.format.defaults = {
+		// token definitions
+		escape: /\[(.+?)\]/,
+		years: /[Yy]+/,
+		months: /M+/,
+		weeks: /[Ww]+/,
+		days: /[Dd]+/,
+		hours: /[Hh]+/,
+		minutes: /m+/,
+		seconds: /s+/,
+		milliseconds: /S+/,
+		general: /.+?/,
+
+		// token type names
+		// in order of descending magnitude
+		// can be a space-separated token name list or an array of token names
+		types: "escape years months weeks days hours minutes seconds milliseconds general",
+
+		// format options
+
+		// trim
+		// "left" - template tokens are trimmed from the left until the first moment token that has a value >= 1
+		// "right" - template tokens are trimmed from the right until the first moment token that has a value >= 1
+		// (the final moment token is not trimmed, regardless of value)
+		// `false` - template tokens are not trimmed
+		trim: "left",
+
+		// precision
+		// number of decimal digits to include after (to the right of) the decimal point (positive integer)
+		// or the number of digits to truncate to 0 before (to the left of) the decimal point (negative integer)
+		precision: 0,
+
+		// force first moment token with a value to render at full length even when template is trimmed and first moment token has length of 1
+		forceLength: null,
+
+		// template used to format duration
+		// may be a function or a string
+		// template functions are executed with the `this` binding of the settings object
+		// so that template strings may be dynamically generated based on the duration object
+		// (accessible via `this.duration`)
+		// or any of the other settings
+		template: function () {
+			var types = this.types,
+				dur = this.duration,
+				lastType = findLast(types, function (type) {
+					return dur._data[type];
+				});
+
+			// default template strings for each duration dimension type
+			switch (lastType) {
+				case "seconds":
+					return "h:mm:ss";
+				case "minutes":
+					return "d[d] h:mm";
+				case "hours":
+					return "d[d] h[h]";
+				case "days":
+					return "M[m] d[d]";
+				case "weeks":
+					return "y[y] w[w]";
+				case "months":
+					return "y[y] M[m]";
+				case "years":
+					return "y[y]";
+				default:
+					return "y[y] M[m] d[d] h:mm:ss";
+			}
+		}
+	};
+
+})(this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/view.xml b/contrib/views/pig/src/main/resources/view.xml
index 7f59758..9c92a3b 100644
--- a/contrib/views/pig/src/main/resources/view.xml
+++ b/contrib/views/pig/src/main/resources/view.xml
@@ -19,56 +19,58 @@
     <label>Pig</label>
     <version>0.1.0</version>
 
-    <!-- HDFS parameters -->
+    <!-- HDFS Configs -->
     <parameter>
-        <name>dataworker.defaultFs</name>
-        <description>FileSystem URI</description>
+        <name>webhdfs.url</name>
+        <description>WebHDFS FileSystem URI (example: webhdfs://namenode:50070)</description>
         <required>true</required>
     </parameter>
 
     <parameter>
-        <name>dataworker.hdfs.username</name>
-        <description>HDFS user.name and doAs</description>
+        <name>webhdfs.username</name>
+        <description>User and doAs for proxy user for HDFS</description>
         <required>false</required>
     </parameter>
 
+    <!-- WebHCat Configs -->
     <parameter>
-        <name>dataworker.username</name>
-        <description>The username (defaults to ViewContext username)</description>
-        <required>false</required>
-    </parameter>
-
-    <parameter>
-        <name>dataworker.scripts.path</name>
-        <description>Directory to store scripts</description>
+        <name>webhcat.url</name>
+        <description>WebHCat URL (example: http://webhcat.host:50111/templeton)</description>
         <required>true</required>
     </parameter>
+
     <parameter>
-        <name>dataworker.jobs.path</name>
-        <description>Directory to store jobs (for templeton status dir)</description>
-        <required>true</required>
+        <name>webhcat.username</name>
+        <description>User and doAs for proxy user for WebHCat</description>
+        <required>false</required>
     </parameter>
 
-    <!-- Pig parameters -->
+    <!-- General Configs -->
 
     <parameter>
-        <name>dataworker.storagePath</name>
-        <description>Persistent storage path</description>
+        <name>dataworker.username</name>
+        <description>The username (defaults to ViewContext username)</description>
         <required>false</required>
     </parameter>
 
     <parameter>
-        <name>dataworker.webhcat.url</name>
-        <description>Templeton url</description>
+        <name>scripts.dir</name>
+        <description>HDFS directory path to store Pig scripts (example: /users/${username})</description>
         <required>true</required>
     </parameter>
 
     <parameter>
-        <name>dataworker.webhcat.user</name>
-        <description>Templeton user.name and doAs</description>
+        <name>jobs.dir</name>
+        <description>HDFS directory path to store Pig job status (example: /users/${username})</description>
         <required>true</required>
     </parameter>
 
+    <parameter>
+        <name>store.dir</name>
+        <description>HDFS directory to store meta information about Pig scripts and jobs (example: /users/${username})</description>
+        <required>false</required>
+    </parameter>
+
     <resource>
         <name>script</name>
         <plural-name>scripts</plural-name>
@@ -106,4 +108,23 @@
         <service-class>org.apache.ambari.view.pig.PigServiceRouter</service-class>
     </resource>
 
+    <persistence>
+        <entity>
+            <class>org.apache.ambari.view.pig.persistence.DataStoreStorage$SmokeTestEntity</class>
+            <id-property>id</id-property>
+        </entity>
+        <entity>
+            <class>org.apache.ambari.view.pig.resources.jobs.models.PigJob</class>
+            <id-property>id</id-property>
+        </entity>
+        <entity>
+            <class>org.apache.ambari.view.pig.resources.scripts.models.PigScript</class>
+            <id-property>id</id-property>
+        </entity>
+        <entity>
+            <class>org.apache.ambari.view.pig.resources.udf.models.UDF</class>
+            <id-property>id</id-property>
+        </entity>
+    </persistence>
+
 </view>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
index ab158a3..ff34247 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
@@ -48,6 +48,10 @@ public abstract class BasePigTest {
     FileUtil.fullyDelete(baseDir);
   }
 
+  @AfterClass
+  public static void shutDown() throws Exception {
+  }
+
   @Before
   public void setUp() throws Exception {
     handler = createNiceMock(ViewResourceHandler.class);
@@ -56,19 +60,20 @@ public abstract class BasePigTest {
     properties = new HashMap<String, String>();
     baseDir = new File(DATA_DIRECTORY)
         .getAbsoluteFile();
-    pigStorageFile = new File("./target/BasePigTest/storage.dat")
+    pigStorageFile = new File("./target/PigTest/storage.dat")
         .getAbsoluteFile();
 
     properties.put("dataworker.storagePath", pigStorageFile.toString());
-    properties.put("dataworker.webhcat.url", "localhost:50111/templeton/v1");
-    properties.put("dataworker.webhcat.user", "admin");
-    properties.put("dataworker.scripts.path", "/tmp/.pigscripts");
-    properties.put("dataworker.jobs.path", "/tmp/.pigjobs");
+    properties.put("webhcat.url", "localhost:50111/templeton/v1");
+    properties.put("webhcat.username", "admin");
+    properties.put("scripts.dir", "/tmp/.pigscripts");
+    properties.put("jobs.dir", "/tmp/.pigjobs");
 
     setupProperties(properties, baseDir);
 
     expect(context.getProperties()).andReturn(properties).anyTimes();
     expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context.getInstanceName()).andReturn("MyPig").anyTimes();
 
     replay(handler, context);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
index 85a67f6..37b316f 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
@@ -48,6 +48,7 @@ public abstract class HDFSTest extends BasePigTest {
 
   @AfterClass
   public static void shutDown() throws Exception {
+    BasePigTest.shutDown();
     hdfsCluster.shutdown();
     hdfsCluster = null;
   }
@@ -55,6 +56,6 @@ public abstract class HDFSTest extends BasePigTest {
   @Override
   protected void setupProperties(Map<String, String> properties, File baseDir) throws Exception {
     super.setupProperties(properties, baseDir);
-    properties.put("dataworker.defaultFs", hdfsURI);
+    properties.put("webhdfs.url", hdfsURI);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
index 35cffbd..ba04599 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
@@ -21,10 +21,7 @@ package org.apache.ambari.view.pig.test;
 import org.apache.ambari.view.pig.HDFSTest;
 import org.apache.ambari.view.pig.resources.files.FileResource;
 import org.apache.ambari.view.pig.resources.files.FileService;
-import org.apache.ambari.view.pig.utils.BadRequestFormattedException;
-import org.apache.ambari.view.pig.utils.FilePaginator;
-import org.apache.ambari.view.pig.utils.NotFoundFormattedException;
-import org.apache.ambari.view.pig.utils.ServiceFormattedException;
+import org.apache.ambari.view.pig.utils.*;
 import org.json.simple.JSONObject;
 import org.junit.*;
 import org.junit.rules.ExpectedException;
@@ -61,7 +58,7 @@ public class FileTest extends HDFSTest {
   @AfterClass
   public static void shutDown() throws Exception {
     HDFSTest.shutDown(); // super
-    FileService.setHdfsApi(null); //cleanup API connection
+    HdfsApi.dropAllConnections(); //cleanup API connection
   }
 
   private Response doCreateFile() throws IOException, InterruptedException {

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
index 167317d..c72da19 100644
--- a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
@@ -21,6 +21,7 @@ package org.apache.ambari.view.pig.test;
 import org.apache.ambari.view.pig.HDFSTest;
 import org.apache.ambari.view.pig.resources.files.FileService;
 import org.apache.ambari.view.pig.services.HelpService;
+import org.apache.ambari.view.pig.utils.HdfsApi;
 import org.json.simple.JSONObject;
 import org.junit.*;
 
@@ -44,7 +45,7 @@ public class HelpTest extends HDFSTest {
   @AfterClass
   public static void shutDown() throws Exception {
     HDFSTest.shutDown(); // super
-    FileService.setHdfsApi(null); //cleanup API connection
+    HdfsApi.dropAllConnections(); //cleanup API connection
   }
 
   @Test
@@ -53,7 +54,7 @@ public class HelpTest extends HDFSTest {
     Assert.assertEquals(200, response.getStatus());
 
     JSONObject obj = (JSONObject)response.getEntity();
-    Assert.assertTrue(obj.containsKey("dataworker.defaultFs"));
-    Assert.assertEquals(hdfsURI, obj.get("dataworker.defaultFs"));
+    Assert.assertTrue(obj.containsKey("webhdfs.url"));
+    Assert.assertEquals(hdfsURI, obj.get("webhdfs.url"));
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/IntegrationalTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/IntegrationalTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/IntegrationalTest.java
new file mode 100644
index 0000000..1a5fcf9
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/IntegrationalTest.java
@@ -0,0 +1,134 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.persistence.Storage;
+import org.apache.ambari.view.pig.persistence.utils.StorageUtil;
+import org.apache.ambari.view.pig.resources.jobs.JobService;
+import org.apache.ambari.view.pig.resources.scripts.ScriptService;
+import org.apache.ambari.view.pig.utils.HdfsApi;
+import org.junit.*;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * Test cases that verify all services altogether
+ */
+public class IntegrationalTest extends HDFSTest {
+  private JobService jobService;
+  private ScriptService scriptService;
+
+  @BeforeClass
+  public static void startUp() throws Exception {
+      HDFSTest.startUp(); // super
+  }
+
+  @AfterClass
+  public static void shutDown() throws Exception {
+      HDFSTest.shutDown(); // super
+      HdfsApi.dropAllConnections(); //cleanup API connection
+  }
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+      super.setUp();
+      jobService = getService(JobService.class, handler, context);
+      scriptService = getService(ScriptService.class, handler, context);
+  }
+
+  @Override
+  @After
+  public void tearDown() throws Exception {
+      super.tearDown();
+      jobService.getResourceManager().setTempletonApi(null);
+      HdfsApi.dropAllConnections();
+  }
+
+  @Test
+  public void testHdfsApiDependsOnInstance() throws Exception {
+    HdfsApi.dropAllConnections();
+
+    ViewContext context1 = createNiceMock(ViewContext.class);
+    ViewContext context2 = createNiceMock(ViewContext.class);
+    ViewContext context3 = createNiceMock(ViewContext.class);
+    expect(context1.getProperties()).andReturn(properties).anyTimes();
+    expect(context1.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context1.getInstanceName()).andReturn("Pig1").anyTimes();
+
+    expect(context2.getProperties()).andReturn(properties).anyTimes();
+    expect(context2.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context2.getInstanceName()).andReturn("Pig2").anyTimes();
+
+    expect(context3.getProperties()).andReturn(properties).anyTimes();
+    expect(context3.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context3.getInstanceName()).andReturn("Pig1").anyTimes();
+
+    replay(context1, context2, context3);
+
+    HdfsApi hdfsApi1 = HdfsApi.getInstance(context1);
+    HdfsApi hdfsApi2 = HdfsApi.getInstance(context2);
+    Assert.assertNotSame(hdfsApi1, hdfsApi2);
+
+    HdfsApi hdfsApi1_2 = HdfsApi.getInstance(context1);
+    HdfsApi hdfsApi2_2 = HdfsApi.getInstance(context1);
+    Assert.assertSame(hdfsApi1_2, hdfsApi2_2);
+
+    HdfsApi hdfsApi1_3 = HdfsApi.getInstance(context1);
+    HdfsApi hdfsApi3_3 = HdfsApi.getInstance(context3);
+    Assert.assertSame(hdfsApi1_3, hdfsApi3_3);
+  }
+
+  @Test
+  public void testStorageDependsOnInstance() throws Exception {
+    StorageUtil.dropAllConnections();
+
+    ViewContext context1 = createNiceMock(ViewContext.class);
+    ViewContext context2 = createNiceMock(ViewContext.class);
+    ViewContext context3 = createNiceMock(ViewContext.class);
+    expect(context1.getProperties()).andReturn(properties).anyTimes();
+    expect(context1.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context1.getInstanceName()).andReturn("Pig1").anyTimes();
+
+    expect(context2.getProperties()).andReturn(properties).anyTimes();
+    expect(context2.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context2.getInstanceName()).andReturn("Pig2").anyTimes();
+
+    expect(context3.getProperties()).andReturn(properties).anyTimes();
+    expect(context3.getUsername()).andReturn("ambari-qa").anyTimes();
+    expect(context3.getInstanceName()).andReturn("Pig1").anyTimes();
+
+    replay(context1, context2, context3);
+
+    Storage storage1 = StorageUtil.getInstance(context1).getStorage();
+    Storage storage2 = StorageUtil.getInstance(context2).getStorage();
+    Assert.assertNotSame(storage1, storage2);
+
+    Storage storage1_2 = StorageUtil.getInstance(context1).getStorage();
+    Storage storage2_2 = StorageUtil.getInstance(context1).getStorage();
+    Assert.assertSame(storage1_2, storage2_2);
+
+    Storage storage1_3 = StorageUtil.getInstance(context1).getStorage();
+    Storage storage3_3 = StorageUtil.getInstance(context3).getStorage();
+    Assert.assertSame(storage1_3, storage3_3);
+  }
+}


[09/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.svg
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.svg b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000..b612969
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.svg
@@ -0,0 +1,520 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="fontawesomeregular" horiz-adv-x="1536" >
+<font-face units-per-em="1792" ascent="1536" descent="-256" />
+<missing-glyph horiz-adv-x="448" />
+<glyph unicode=" "  horiz-adv-x="448" />
+<glyph unicode="&#x09;" horiz-adv-x="448" />
+<glyph unicode="&#xa0;" horiz-adv-x="448" />
+<glyph unicode="&#xa8;" horiz-adv-x="1792" />
+<glyph unicode="&#xa9;" horiz-adv-x="1792" />
+<glyph unicode="&#xae;" horiz-adv-x="1792" />
+<glyph unicode="&#xb4;" horiz-adv-x="1792" />
+<glyph unicode="&#xc6;" horiz-adv-x="1792" />
+<glyph unicode="&#xd8;" horiz-adv-x="1792" />
+<glyph unicode="&#x2000;" horiz-adv-x="768" />
+<glyph unicode="&#x2001;" horiz-adv-x="1537" />
+<glyph unicode="&#x2002;" horiz-adv-x="768" />
+<glyph unicode="&#x2003;" horiz-adv-x="1537" />
+<glyph unicode="&#x2004;" horiz-adv-x="512" />
+<glyph unicode="&#x2005;" horiz-adv-x="384" />
+<glyph unicode="&#x2006;" horiz-adv-x="256" />
+<glyph unicode="&#x2007;" horiz-adv-x="256" />
+<glyph unicode="&#x2008;" horiz-adv-x="192" />
+<glyph unicode="&#x2009;" horiz-adv-x="307" />
+<glyph unicode="&#x200a;" horiz-adv-x="85" />
+<glyph unicode="&#x202f;" horiz-adv-x="307" />
+<glyph unicode="&#x205f;" horiz-adv-x="384" />
+<glyph unicode="&#x2122;" horiz-adv-x="1792" />
+<glyph unicode="&#x221e;" horiz-adv-x="1792" />
+<glyph unicode="&#x2260;" horiz-adv-x="1792" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
+<glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
+<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
+<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
+<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
+<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t1
 9 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28
 t28 -68z" />
+<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
+<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
+<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
+<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
+<glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
+<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
+<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
+<glyph unicode="&#xf016;" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z " />
+<glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
+<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
+<glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
+<glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
+<glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
+<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -1
 13 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
+<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
+<glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
+<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
+<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
+<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
+<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
+<glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
+<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
+<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
+<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
+<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
+<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
+<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
+<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
+<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
+<glyph unicode="&#xf035;" d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41
 .5t-59.5 49t-36 30q-26 21 -26 49 t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
+<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t
 -22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
+<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
+<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
+<glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
+<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
+<glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
+<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
+<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
+<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
+<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
+<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
+<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
+<glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
+<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
+<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
+<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
+<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
+<glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
+<glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
+<glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
+<glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
+<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
+<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
+<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
+<glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
+<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
+<glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
+<glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
+<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
+<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
+<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
+<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
+<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
+<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
+<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
+<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
+<glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
+<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
+<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
+<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
+<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
+<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
+<glyph unicode="&#xf080;" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
+<glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf082;" d="M1536 160q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5v-960z" />
+<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
+<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 
 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
+<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
+<glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
+<glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
+<glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
+<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
+<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
+<glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
+<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
+<glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
+<glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 
 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
+<glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
+<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
+<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
+<glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
+<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
+<glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
+<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
+<glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
+<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
+<glyph unicode="&#xf0a2;" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
+<glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
+<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
+<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
+<glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
+<glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
+<glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17
 t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-1
 5 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q
 -15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21

<TRUNCATED>

[05/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
index 869eecb..a23264a 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
@@ -19,41 +19,58 @@
 var App = require('app');
 
 App.PigView = Em.View.extend({
+  hideScript:true,
   selectedBinding: 'controller.category',
-  navs: Ember.computed(function() {
-    var items = [ 
-      {name:'scripts',url:'pig.scriptList',label: Em.I18n.t('scripts.scripts')},
-      {name:'udfs',url:'pig.udfs',label:Em.I18n.t('udfs.udfs')},
-      {name:'history',url:'pig.history',label:Em.I18n.t('common.history')}
-    ];
-    this.get('controller.openScripts').forEach(function(scripts){
-      items.push(scripts);
-    });
-    return items;
-  }).property('controller.openScripts'),
+  navs: [
+    {name:'scripts',url:'pig.scripts',label: Em.I18n.t('scripts.scripts'),icon:'fa-file-code-o'},
+    {name:'udfs',url:'pig.udfs',label:Em.I18n.t('udfs.udfs'),icon:'fa-plug'},
+    {name:'history',url:'pig.history',label:Em.I18n.t('common.history'),icon:'fa-clock-o'}
+  ],
+
+  initToolip:function () {
+    this.$('button.close_script').tooltip({title:Em.I18n.t('common.close'),placement:'bottom',container:'body'});
+  }.on('didInsertElement'),
+
+  showSideBar:function () {
+    Em.run.later(this, function (show) {
+      this.$('.nav-script-wrap').toggleClass('in',show);
+    },!!this.get('controller.activeScript'),250);
+  }.observes('controller.activeScript'),
+
   navItemsView : Ember.CollectionView.extend({
-    classNames: ['list-group'],
     tagName: 'div',
+    classNames:['list-group', 'nav-main'],
     content: function () { 
       return this.get('parentView.navs')
     }.property('parentView.navs'),
+    mouseEnter:function  (argument) {
+      this.get('parentView').$('.nav-script-wrap').addClass('reveal');
+    },
+    mouseLeave:function  (argument) {
+      this.get('parentView').$('.nav-script-wrap').removeClass('reveal');
+    },
     itemViewClass: Ember.View.extend(Ember.ViewTargetActionSupport,{
       tagName: 'a',
-      templateName: 'pig/util/script-nav',
-      classNames: ['list-group-item pig-nav-item'],
+      template: Em.Handlebars.compile(
+        '<i class="fa fa-fw fa-2x {{unbound view.content.icon}}"></i> '+
+        '<span>{{view.content.label}}</span>'
+      ),
+      classNames: ['list-group-item pig-nav-item text-left'],
       classNameBindings: ['isActive:active'],
       action: 'gotoSection',
       click: function(e) {
         if (e.target.type=="button") {
           return false;
-        };
+        }
         this.triggerAction({
           actionContext:this.content
         }); 
       },
       isActive: function () {
         return this.get('content.name') === this.get('parentView.parentView.selected');
-      }.property('content.name', 'parentView.parentView.selected')
+      }.property('content.name', 'parentView.parentView.selected'),
+
+      hideLabel:Em.computed.bool('controller.activeScript')
     })
   })
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/alert.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/alert.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/alert.js
new file mode 100644
index 0000000..84a2c82
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/alert.js
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigAlertView = Ember.View.extend({
+  alertsView : Ember.CollectionView.extend({
+    content: function () {
+      return this.get('controller.content');
+    }.property('controller.content'),
+    itemViewClass: Ember.View.extend({
+      classNames: ['alert fade in'],
+      classNameBindings: ['alertClass'],
+      attributeBindings:['dismiss:data-dismiss'],
+      dismiss:'alert',
+      templateName: 'partials/alert-content',
+      didInsertElement:function () {
+        var self = this;
+
+        $(self.get('element')).bind('closed.bs.alert', function (e) {
+          return self.clearAlert();
+        });
+
+        if (this.get('content.status')!='error') {
+          Ember.run.debounce(self, self.close, 3000);
+        }
+      },
+      close : function (argument) {
+        return $(this.get('element')).alert('close');
+      },
+      clearAlert:function () {
+        return this.get('controller').send('removeAlertObject',this.content);
+      },
+      alertClass: function () {
+        var classes = {'success':'alert-success','error':'alert-danger','info':'alert-info'};
+        return classes[this.get('content.status')];
+      }.property('content.status')
+    })
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/history.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/history.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/history.js
new file mode 100644
index 0000000..9ad0ae1
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/history.js
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigHistoryView = Em.View.extend({
+  initTooltips:function () {
+    if ( this.$('td:last-child a')) {
+      Em.run.next(this.addTooltip.bind(this))
+    }
+  }.on('didInsertElement').observes('controller.page','controller.content.@each'),
+  addTooltip:function () {
+    this.$('td:last-child a').tooltip({placement:'bottom'})
+  },
+  scriptLink:Em.Component.extend({
+    tagName:'a',
+    classNames:['scriptLink'],
+    classNameBindings:['hasScript::inactive'],
+    action:'goToScript',
+    hasScript:function () {
+      var all = this.get('allIds'),
+          current = (this.get('scriptId'))?this.get('scriptId').toString():'';
+      return all.contains(current);
+    }.property('scriptId'),
+    click:function () {
+      if (this.get('hasScript')) {
+        this.sendAction('action',this.get('scriptId'));
+      }
+    }
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js
deleted file mode 100644
index 15bf89b..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.JobResultsView = Em.View.extend({
-    templateName: 'pig/jobResults',
-    outputView: Em.View.extend({
-      classNames: ['panel panel-default panel-results'],
-      templateName: 'pig/jobResultsOutput',
-      didInsertElement:function () {
-          $('#btn-stdout').button({'loadingText':Em.I18n.t('job.job_results.stdout_loading')});
-          $('#btn-stderr').button({'loadingText':Em.I18n.t('job.job_results.stderr_loading')});
-          $('#btn-exitcode').button({'loadingText':Em.I18n.t('job.job_results.exitcode_loading')});
-      },
-      actions:{
-        getOutput:function (item) {
-          var self = this;
-          var controller = this.get('controller');
-          output = controller.get(item); 
-          if (!output) {
-            return;
-          };
-          $(this.get('element')).find('.btn').removeClass('active');
-          $('#btn-'+item).button('loading');
-          this.set('isLoadingOutput',true);
-          output.then(function (result) {
-            $('#btn-'+item).button('reset').addClass('active');
-            self.set('isLoadingOutput',false);
-            self.set('activeOutput',result.fileContent);
-          })
-        }
-      },
-      isLoadingOutput:false,
-      activeOutput:'Select output.'
-    })
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/loading.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/loading.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/loading.js
new file mode 100644
index 0000000..2cbe873
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/loading.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.LoadingView = Em.View.extend({
+  template: Em.Handlebars.compile('<div class="spinner-bg center-block"></div>')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js
deleted file mode 100644
index f8e59d1..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.ConfirmDeleteView = App.PigModalView.extend({
-  templateName:'pig/modal/confirmdelete',
-  actions:{
-    confirm:function(script) {
-      $(this.get('element')).find('.modal').modal('hide');
-      return this.controller.send('confirmdelete',script);
-    }
-  },
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js
deleted file mode 100644
index becf47e..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.CreateScriptView = App.PigModalView.extend({
-  templateName: 'pig/modal/createScript',
-  actions:{
-    create: function(script) {
-      var title = this.controller.get('title');
-      if (!title) {
-        this.controller.set('error', Em.I18n.t('scripts.modal.error_empty_title'))
-        return;
-      }
-      var filePath = this.controller.get('filePath');
-      $(this.get('element')).find('.modal').modal('hide');
-      return this.controller.send('confirmcreate',script,filePath);
-    },
-    close:function (script) {
-      script.deleteRecord();
-      return this._super();
-    }
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js
deleted file mode 100644
index 22ed431..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.CreateUdfView = App.PigModalView.extend({
-  templateName: 'pig/modal/createUdf',
-  actions:{
-    createUdf: function(udf) {
-      $(this.get('element')).find('.modal').modal('hide');
-      return this.controller.send('createUdf',udf);
-    },
-    close:function (udf) {
-      udf.deleteRecord();
-      return this._super();
-    }
-  },
-  udfInvalid:function (argument) {
-    var udf = this.get('controller.content');
-    var invalid = !udf.get('name') || !udf.get('path');
-    return invalid;
-  }.property('controller.content.name','controller.content.path'),
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js
deleted file mode 100644
index d86e9fe..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigModalView = Ember.View.extend({
-  actions:{
-    close:function() {
-      return $(this.get('element')).find('.modal').modal('hide');
-    }
-  },
-  didInsertElement: function() {
-    var view = this;
-    $(this.get('element')).find('.modal').modal('show');
-    return this.$('.modal').on("hidden.bs.modal", function(ev) {
-      view.controller.send('closeModal');
-    });
-  },
-  layoutName:'pig/modal/modalLayout'
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js
deleted file mode 100644
index 1ee56a5..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigHistoryView = Em.View.extend({
-  historyTableRow:Ember.View.extend({
-    statuses:{
-      'SUBMITTING':'success',
-      'SUBMITTED':'success',
-      'RUNNING':'warning',
-      'COMPLETED':'success',
-      'SUBMIT_FAILED':'danger',
-      'KILLED':'danger',
-      'FAILED':'danger'
-    },
-    labelClass:function () {
-      return 'label-'+this.statuses[this.get('context.status')];
-    }.property('context.status'),
-  })
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js
deleted file mode 100644
index 09d17dc..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigJobView = Em.View.extend({
-    templateName: 'pig/job',
-    classNames:['job-status-view'],
-    actions:{
-      editJob:function (job) {
-        job.store.createRecord('job',{pigScript: job.get('pigScript'),title:job.get('title')});
-        return 
-      }
-    },
-    progressBar: Em.View.extend({
-      classNames:['progress'],
-      didInsertElement:function () {
-        this.update();
-      },
-      update:function () {
-        var progress = (!this.get('content.isTerminated'))?this.get('content.percentStatus'):100;
-        $(this.get('element')).find('.progress-bar').css('width',progress+'%');
-      }.observes('content.percentStatus'),
-      template:Em.Handlebars.compile('<div {{bind-attr class=":progress-bar content.isTerminated:progress-bar-danger:progress-bar-success" }}role="progressbar"></div>')
-    })
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js
deleted file mode 100644
index 81bc4f6..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigUdfsView = Em.View.extend({
-    templateName: 'pig/udfs'
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js
deleted file mode 100644
index 109cc43..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptEditView = Em.View.extend({
-  didInsertElement:function () {
-    $('.file-path').tooltip();
-    if (this.get('controller.isJob')) {
-      this.set('isEditConfirmed',false);
-    };
-  },
-  actions:{
-    insertUdf:function (udf) {
-      var cm = this.get('codeMirror');
-      cm.setValue('REGISTER ' + udf.get('path') + '\n'+ cm.getValue());
-    },
-    confirmEdit:function () {
-      this.set('isEditConfirmed', true);
-    }
-  },
-  argumentInput: Ember.TextField.extend({
-    viewName:"argumentInput",
-    actions:{
-      sendArgument:function(){
-        this.get('parentView.controller').send('addArgument',this.get('value'));
-        this.set('value',null);
-      }
-    },
-    classNames:["form-control argadd"],
-    keyPress:function  (event) {
-      if (event.keyCode=="13") {
-        this.send('sendArgument');
-      }
-    }
-  }),
-  showEditor:function () {
-    return this.get('controller.category')!='results';
-  }.property('controller.category','codeMirror'),
-  codeMirror:null,
-  codeMirrorView: Ember.TextArea.extend({
-    valueBinding:"content.fileContent",
-    updateCM:function (view,trigger) {
-      var cm = this.get('parentView.codeMirror');
-      var cmElement = $(cm.display.wrapper);
-      if (this.get('content.isLoaded')) {
-        if (this.get('parentView.controller.isJob') && !this.get('parentView.isEditConfirmed')) {
-          cm.setOption('readOnly',true);
-          cmElement.addClass('inactive');
-        } else {
-          cm.setOption('readOnly',false);
-          cmElement.removeClass('inactive')
-        }
-        this.get('parentView.codeMirror').setValue(this.get('content.fileContent')||'');
-      } else {
-        cm.setOption('readOnly',true);
-        cmElement.addClass('inactive');
-      };
-
-    }.observes('parentView.codeMirror', 'content.didLoad', 'parentView.isEditConfirmed'),
-    didInsertElement: function() {
-      var self = this;
-      var cm = CodeMirror.fromTextArea(this.get('element'),{
-        lineNumbers: true,
-        matchBrackets: true,
-        indentUnit: 4,
-        keyMap: "emacs"
-      });
-      this.set('parentView.codeMirror',cm);
-      cm.on('change',function (cm) {
-        var pig_script = self.get('content');
-        if (pig_script.get('isLoaded')){
-          pig_script.set('fileContent',cm.getValue());
-        }
-      });                  
-    }
-  }),
-  isEditConfirmed: true,
-  pigHelperView: Em.View.extend({
-    actions:{
-      putToEditor:function (helper) {
-        helper = helper.toString();
-        
-        var editor = this.get('parentView.codeMirror');
-        var cursor = editor.getCursor();
-        var pos = this.findPosition(helper);
-        
-        editor.replaceRange(helper, cursor, cursor);
-        editor.focus();
-
-        if (pos.length>1) {
-          editor.setSelection(
-            {line:cursor.line, ch:cursor.ch + pos[0]},
-            {line:cursor.line, ch:cursor.ch + pos[1]+1}
-          );
-        }
-
-        return false;
-      }
-    },
-    findPosition: function (curLine){
-      var pos= curLine.indexOf("%");
-      var posArr=[];
-      while(pos > -1) {
-        posArr.push(pos);
-        pos = curLine.indexOf("%", pos+1);
-      }
-      return posArr;
-    },
-    templateName:'pig/util/pigHelper',
-    helpers:[
-      {
-        'title':'Eval Functions',
-        'helpers':[
-          'AVG(%VAR%)',
-          'CONCAT(%VAR1%, %VAR2%)',
-          'COUNT(%VAR%)',
-          'COUNT_START(%VAR%)',
-          'IsEmpty(%VAR%)',
-          'DIFF(%VAR1%, %VAR2%)',
-          'MAX(%VAR%)',
-          'MIN(%VAR%)',
-          'SIZE(%VAR%)',
-          'SUM(%VAR%)',
-          'TOKENIZE(%VAR%, %DELIM%)',
-        ]
-      },
-      {
-        'title':'Relational Operators',
-        'helpers':[
-          'COGROUP %VAR% BY %VAR%',
-          'CROSS %VAR1%, %VAR2%;',
-          'DISTINCT %VAR%;',
-          'FILTER %VAR% BY %COND%',
-          'FLATTEN(%VAR%)',
-          'FOREACH %DATA% GENERATE %NEW_DATA%',
-          'FOREACH %DATA% {%NESTED_BLOCK%}',
-          'GROUP %VAR% BY %VAR%',
-          'GROUP %VAR% ALL',
-          'JOIN %VAR% BY ',
-          'LIMIT %VAR% %N%',
-          'ORDER %VAR% BY %FIELD%',
-          'SAMPLE %VAR% %SIZE%',
-          'SPLIT %VAR1% INTO %VAR2% IF %EXPRESSIONS%',
-          'UNION %VAR1%, %VAR2%',
-        ]
-      },
-      {
-        'title':'I/0',
-        'helpers':[
-          "LOAD '%FILE%';",
-          'DUMP %VAR%;',
-          'STORE %VAR% INTO %PATH%;',
-        ]
-      },
-      {
-        'title':'Debug',
-        'helpers':[
-          'EXPLAIN %VAR%;',
-          'ILLUSTRATE %VAR%;',
-          'DESCRIBE %VAR%;',
-        ]
-      },
-      {
-        'title':'HCatalog',
-        'helpers':[
-          "LOAD '%TABLE%' USING org.apache.hcatalog.pig.HCatLoader();",
-        ]
-      },
-      {
-        'title':'Math',
-        'helpers':[
-          'ABS(%VAR%)',
-          'ACOS(%VAR%)',
-          'ASIN(%VAR%)',
-          'ATAN(%VAR%)',
-          'CBRT(%VAR%)',
-          'CEIL(%VAR%)',
-          'COS(%VAR%)',
-          'COSH(%VAR%)',
-          'EXP(%VAR%)',
-          'FLOOR(%VAR%)',
-          'LOG(%VAR%)',
-          'LOG10(%VAR%)',
-          'RANDOM(%VAR%)',
-          'ROUND(%VAR%)',
-          'SIN(%VAR%)',
-          'SINH(%VAR%)',
-          'SQRT(%VAR%)',
-          'TAN(%VAR%)',
-          'TANH(%VAR%)',
-        ]
-      },
-      {
-        'title':'Tuple, Bag, Map Functions',
-        'helpers':[
-          'TOTUPLE(%VAR%)',
-          'TOBAG(%VAR%)',
-          'TOMAP(%KEY%, %VALUE%)',
-          'TOP(%topN%, %COLUMN%, %RELATION%)',
-        ]
-      },
-      {
-        'title':'String Functions',
-        'helpers':[
-          "INDEXOF(%STRING%, '%CHARACTER%', %STARTINDEX%)",
-          "LAST_INDEX_OF(%STRING%, '%CHARACTER%', %STARTINDEX%)",
-          "LOWER(%STRING%)",
-          "REGEX_EXTRACT(%STRING%, %REGEX%, %INDEX%)",
-          "REGEX_EXTRACT_ALL(%STRING%, %REGEX%)",
-          "REPLACE(%STRING%, '%oldChar%', '%newChar%')",
-          "STRSPLIT(%STRING%, %REGEX%, %LIMIT%)",
-          "SUBSTRING(%STRING%, %STARTINDEX%, %STOPINDEX%)",
-          "TRIM(%STRING%)",
-          "UCFIRST(%STRING%)",
-          "UPPER(%STRING%)",
-        ]
-      },
-      {
-        'title':'Macros',
-        'helpers':[
-          "IMPORT '%PATH_TO_MACRO%';",
-        ]
-      },
-      {
-        'title':'HBase',
-        'helpers':[
-          "LOAD 'hbase://%TABLE%' USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('%columnList%')",
-          "STORE %VAR% INTO 'hbase://%TABLE%' USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('%columnList%')",
-        ]
-      },
-      {
-        'title':'Python UDF',
-        'helpers':[
-          "REGISTER 'python_udf.py' USING jython AS myfuncs;",
-        ]
-      }
-    ]
-  }),
-  pigParamView:Em.TextField.extend({})
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js
deleted file mode 100644
index 50e5a95..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptListView = Em.View.extend({
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js
deleted file mode 100644
index cb9f52c..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptResultsView = Em.View.extend({
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js
deleted file mode 100644
index a9dd420..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptResultsNavView = Em.View.extend({
-  tagName:'span',
-  selectedBinding: 'controller.category',
-  navResultsView : Ember.CollectionView.extend({
-    classNames: ['nav nav-pills nav-results pull-right'],
-    tagName: 'ul',
-    content: function () { 
-      var navs = [ 
-        {name:'edit',route:'job',label:Em.I18n.t('common.edit')},
-        {name:'results',route:'job.results',label:Em.I18n.t('job.results')},
-        //{name:'logs',route:'#',label:Em.I18n.t('job.logs')}
-      ];
-      return navs;
-    }.property(),
-    itemViewClass: Ember.View.extend(Ember.ViewTargetActionSupport,{
-      actions:{
-        switch:function (argument) {
-          return this.send('navigate',argument)
-        }
-      },
-      tagName: 'li',
-      template: Ember.Handlebars.compile('<a href="#" {{action "switch" view.content target="view"}} >{{view.content.label}}</a>'),
-      classNameBindings: ['isActive:active'],
-      isActive: function () {
-        return this.get('content.name') === this.get('parentView.parentView.selected');
-      }.property('content.name', 'parentView.parentView.selected')
-    })
-  })
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scripts.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scripts.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scripts.js
new file mode 100644
index 0000000..61737ce
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scripts.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptsView = Em.View.extend({
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/udfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/udfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/udfs.js
new file mode 100644
index 0000000..99d1949
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/udfs.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigUdfsView = Em.View.extend({
+  templateName: 'pig/udfs'
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js
deleted file mode 100644
index 10e2345..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigUtilAlertView = Ember.View.extend({ 
-  alertsView : Ember.CollectionView.extend({
-    content: function () { 
-      return this.get('controller.content');
-    }.property('controller.content'),
-    itemViewClass: Ember.View.extend({
-      classNames: ['alert fade in'],
-      classNameBindings: ['alertClass'],
-      attributeBindings:['dismiss:data-dismiss'],
-      dismiss:'alert',
-      templateName: 'pig/util/alert-content',
-      didInsertElement:function () {
-        var self = this;
-        
-        $(self.get('element')).bind('closed.bs.alert', function (e) {
-          return self.clearAlert();
-        });
-
-        if (this.get('content.status')!='error') {
-          Ember.run.debounce(self, self.close, 3000);
-        };
-      },
-      close : function (argument) {
-        return $(this.get('element')).alert('close');
-      },
-      clearAlert:function () {
-        return this.get('controller').send('removeAlertObject',this.content);
-      },
-      alertClass: function () {
-        var classes = {'success':'alert-success','error':'alert-danger','info':'alert-info'};
-        return classes[this.get('content.status')];
-      }.property('content.status')
-    })
-  })
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/edit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/edit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/edit.js
new file mode 100644
index 0000000..9a10292
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/edit.js
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptEditView = Em.View.extend({
+  didInsertElement:function () {
+    $('.file-path').tooltip();
+  },
+  showTitleWarn:function () {
+    if (this.get('controller.titleWarn')) {
+      this.$('#title').tooltip({
+        trigger:"manual",
+        placement:"bottom",
+        title:Em.I18n.t('scripts.alert.rename_unfinished')
+      }).tooltip('show');
+    }
+  }.observes('controller.titleWarn'),
+  actions:{
+    insertUdf:function () {
+      var code = this.get('controller.content.pigScript.fileContent'),
+      registered = 'REGISTER ' + udf.get('path') + '\n' + code;
+      this.set('controller.content.pigScript.fileContent',registered);
+    }
+  },
+  argumentInput: Ember.TextField.extend({
+    viewName:"argumentInput",
+    actions:{
+      sendArgument:function(){
+        this.get('parentView.controller').send('addArgument',this.get('value'));
+        this.set('value',null);
+      }
+    },
+    classNames:["form-control argadd"],
+    keyPress:function  (event) {
+      if (event.keyCode=="13") {
+        this.send('sendArgument');
+      }
+    }
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/job.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/job.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/job.js
new file mode 100644
index 0000000..5b8af7e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/script/job.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptJobView = Em.View.extend({
+  collapsePanel: Em.View.extend({
+    rotateToggle:function () {
+      this.$().on('hide.bs.collapse', function (e) {
+        this.$().parent().find('.toggle-icon').removeClass('fa-rotate-90');
+      }.bind(this));
+      this.$().on('show.bs.collapse', function (e) {
+        this.$().parent().find('.toggle-icon').addClass('fa-rotate-90');
+      }.bind(this));
+    }.on('didInsertElement'),
+    unbindToggle:function () {
+      this.$().off('hide.bs.collapse','show.bs.collapse');
+    }.on('willClearRender')
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/bower.json b/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
index 44c5247..7d6f5a1 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
@@ -3,20 +3,30 @@
   "version": "0.0.1",
   "main": "public/app.js",
   "dependencies": {
-    "ember": "1.4.0",
-    "ember-data": "1.0.0-beta.5",
+    "ember": "1.6.0",
+    "ember-data": "1.0.0-beta.7",
     "handlebars": "~1.3.0",
-    "bootstrap": "3.0.x",
+    "bootstrap": "3.1.x",
     "codemirror": ">=3.2",
-    "moment": "~2.5.1",
-    "ember-i18n": "~1.6.0"
+    "moment": "~2.8.1",
+    "ember-i18n": "~1.6.0",
+    "font-awesome": "4.2",
+    "file-saver": "*"
   },
   "overrides": {
-    "cldr":{
-      "main":"plurals.js"
+    "bootstrap": {
+      "main": [
+        "./dist/js/bootstrap.js"
+      ]
     },
-    "ember-i18n":{
+    "cldr": {
+      "main": "plurals.js"
+    },
+    "ember-i18n": {
       "scripts": []
+    },
+    "file-saver": {
+      "main": "FileSaver.js"
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee b/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
index f599360..c194b0e 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
@@ -16,12 +16,25 @@
 
 exports.config = 
 
+  watcher:
+    usePolling: true
+
+  fileListInterval: 512
+
   files: 
     javascripts: 
       defaultExtension: 'js'
       joinTo: 
         'static/javascripts/app.js': /^app/
         'static/javascripts/vendor.js': /^bower_components|vendor/
+      order:
+        before: [
+          'bower_components/jquery/dist/jquery.js',
+          'vendor/jquery-ui/core.js',
+          'vendor/jquery-ui/widget.js',
+          'vendor/jquery-ui/mouse.js',
+          'vendor/jquery-ui/position.js',
+        ]
 
     stylesheets:
       defaultExtension: 'css'
@@ -33,19 +46,15 @@ exports.config =
       defaultExtension: 'hbs'
       joinTo: 'static/javascripts/app.js' : /^app/
       paths:
-        jquery: 'bower_components/jquery/jquery.js'
+        jquery: 'bower_components/jquery/dist/jquery.js'
         handlebars: 'bower_components/handlebars/handlebars.js'
         ember: 'bower_components/ember/ember.js'
 
   modules:
     addSourceURLs: true
 
-
-  paths:
-    public: '/usr/lib/ambari-server/web/views-debug/PIG/0.1.0/MyPig/'
-
   overrides:
-    production:
-        paths:
-          public: 'public'
-
+    development:
+      fileListInterval: 64
+      paths:
+        public: '/usr/lib/ambari-server/web/views-debug/PIG/0.1.0/MyPig/'

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/package.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/package.json b/contrib/views/pig/src/main/resources/ui/pig-web/package.json
index abedb74..1bb3cfd 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/package.json
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/package.json
@@ -10,7 +10,7 @@
     "postinstall" : "bash node/with_new_path.sh node node_modules/.bin/bower --allow-root install"
   },
   "dependencies": {
-    "brunch": ">= 1.7.1",
+    "brunch": "1.7.17",
     "javascript-brunch": ">= 1.0 < 1.8",
     "css-brunch": ">= 1.0 < 1.8",
     "uglify-js-brunch": ">= 1.0 < 1.8",

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/core.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/core.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/core.js
new file mode 100644
index 0000000..d14b737
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/jquery-ui/core.js
@@ -0,0 +1,304 @@
+/*!
+ * jQuery UI Core 1.11.2
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/ui-core/
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define( [ "jquery" ], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+// $.ui might exist from components with no dependencies, e.g., $.ui.position
+$.ui = $.ui || {};
+
+$.extend( $.ui, {
+	version: "1.11.2",
+
+	keyCode: {
+		BACKSPACE: 8,
+		COMMA: 188,
+		DELETE: 46,
+		DOWN: 40,
+		END: 35,
+		ENTER: 13,
+		ESCAPE: 27,
+		HOME: 36,
+		LEFT: 37,
+		PAGE_DOWN: 34,
+		PAGE_UP: 33,
+		PERIOD: 190,
+		RIGHT: 39,
+		SPACE: 32,
+		TAB: 9,
+		UP: 38
+	}
+});
+
+// plugins
+$.fn.extend({
+	scrollParent: function( includeHidden ) {
+		var position = this.css( "position" ),
+			excludeStaticParent = position === "absolute",
+			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
+			scrollParent = this.parents().filter( function() {
+				var parent = $( this );
+				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
+					return false;
+				}
+				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
+			}).eq( 0 );
+
+		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
+	},
+
+	uniqueId: (function() {
+		var uuid = 0;
+
+		return function() {
+			return this.each(function() {
+				if ( !this.id ) {
+					this.id = "ui-id-" + ( ++uuid );
+				}
+			});
+		};
+	})(),
+
+	removeUniqueId: function() {
+		return this.each(function() {
+			if ( /^ui-id-\d+$/.test( this.id ) ) {
+				$( this ).removeAttr( "id" );
+			}
+		});
+	}
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+	var map, mapName, img,
+		nodeName = element.nodeName.toLowerCase();
+	if ( "area" === nodeName ) {
+		map = element.parentNode;
+		mapName = map.name;
+		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+			return false;
+		}
+		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
+		return !!img && visible( img );
+	}
+	return ( /input|select|textarea|button|object/.test( nodeName ) ?
+		!element.disabled :
+		"a" === nodeName ?
+			element.href || isTabIndexNotNaN :
+			isTabIndexNotNaN) &&
+		// the element and all of its ancestors must be visible
+		visible( element );
+}
+
+function visible( element ) {
+	return $.expr.filters.visible( element ) &&
+		!$( element ).parents().addBack().filter(function() {
+			return $.css( this, "visibility" ) === "hidden";
+		}).length;
+}
+
+$.extend( $.expr[ ":" ], {
+	data: $.expr.createPseudo ?
+		$.expr.createPseudo(function( dataName ) {
+			return function( elem ) {
+				return !!$.data( elem, dataName );
+			};
+		}) :
+		// support: jQuery <1.8
+		function( elem, i, match ) {
+			return !!$.data( elem, match[ 3 ] );
+		},
+
+	focusable: function( element ) {
+		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+	},
+
+	tabbable: function( element ) {
+		var tabIndex = $.attr( element, "tabindex" ),
+			isTabIndexNaN = isNaN( tabIndex );
+		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+	}
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+	$.each( [ "Width", "Height" ], function( i, name ) {
+		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+			type = name.toLowerCase(),
+			orig = {
+				innerWidth: $.fn.innerWidth,
+				innerHeight: $.fn.innerHeight,
+				outerWidth: $.fn.outerWidth,
+				outerHeight: $.fn.outerHeight
+			};
+
+		function reduce( elem, size, border, margin ) {
+			$.each( side, function() {
+				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+				if ( border ) {
+					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+				}
+				if ( margin ) {
+					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+				}
+			});
+			return size;
+		}
+
+		$.fn[ "inner" + name ] = function( size ) {
+			if ( size === undefined ) {
+				return orig[ "inner" + name ].call( this );
+			}
+
+			return this.each(function() {
+				$( this ).css( type, reduce( this, size ) + "px" );
+			});
+		};
+
+		$.fn[ "outer" + name] = function( size, margin ) {
+			if ( typeof size !== "number" ) {
+				return orig[ "outer" + name ].call( this, size );
+			}
+
+			return this.each(function() {
+				$( this).css( type, reduce( this, size, true, margin ) + "px" );
+			});
+		};
+	});
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+	$.fn.addBack = function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter( selector )
+		);
+	};
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+	$.fn.removeData = (function( removeData ) {
+		return function( key ) {
+			if ( arguments.length ) {
+				return removeData.call( this, $.camelCase( key ) );
+			} else {
+				return removeData.call( this );
+			}
+		};
+	})( $.fn.removeData );
+}
+
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+$.fn.extend({
+	focus: (function( orig ) {
+		return function( delay, fn ) {
+			return typeof delay === "number" ?
+				this.each(function() {
+					var elem = this;
+					setTimeout(function() {
+						$( elem ).focus();
+						if ( fn ) {
+							fn.call( elem );
+						}
+					}, delay );
+				}) :
+				orig.apply( this, arguments );
+		};
+	})( $.fn.focus ),
+
+	disableSelection: (function() {
+		var eventType = "onselectstart" in document.createElement( "div" ) ?
+			"selectstart" :
+			"mousedown";
+
+		return function() {
+			return this.bind( eventType + ".ui-disableSelection", function( event ) {
+				event.preventDefault();
+			});
+		};
+	})(),
+
+	enableSelection: function() {
+		return this.unbind( ".ui-disableSelection" );
+	},
+
+	zIndex: function( zIndex ) {
+		if ( zIndex !== undefined ) {
+			return this.css( "zIndex", zIndex );
+		}
+
+		if ( this.length ) {
+			var elem = $( this[ 0 ] ), position, value;
+			while ( elem.length && elem[ 0 ] !== document ) {
+				// Ignore z-index if position is set to a value where z-index is ignored by the browser
+				// This makes behavior of this function consistent across browsers
+				// WebKit always returns auto if the element is positioned
+				position = elem.css( "position" );
+				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+					// IE returns 0 when zIndex is not specified
+					// other browsers return a string
+					// we ignore the case of nested elements with an explicit value of 0
+					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+					value = parseInt( elem.css( "zIndex" ), 10 );
+					if ( !isNaN( value ) && value !== 0 ) {
+						return value;
+					}
+				}
+				elem = elem.parent();
+			}
+		}
+
+		return 0;
+	}
+});
+
+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
+$.ui.plugin = {
+	add: function( module, option, set ) {
+		var i,
+			proto = $.ui[ module ].prototype;
+		for ( i in set ) {
+			proto.plugins[ i ] = proto.plugins[ i ] || [];
+			proto.plugins[ i ].push( [ option, set[ i ] ] );
+		}
+	},
+	call: function( instance, name, args, allowDisconnected ) {
+		var i,
+			set = instance.plugins[ name ];
+
+		if ( !set ) {
+			return;
+		}
+
+		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
+			return;
+		}
+
+		for ( i = 0; i < set.length; i++ ) {
+			if ( instance.options[ set[ i ][ 0 ] ] ) {
+				set[ i ][ 1 ].apply( instance.element, args );
+			}
+		}
+	}
+};
+
+}));


[08/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.ttf
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.ttf b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..96a3639
Binary files /dev/null and b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.ttf differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.woff
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.woff b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..628b6a5
Binary files /dev/null and b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/components/codeMirror.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/components/codeMirror.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/codeMirror.js
new file mode 100644
index 0000000..dbbac8a
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/codeMirror.js
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.CodeMirrorComponent = Ember.Component.extend({
+  tagName: "textarea",
+  readOnly:false,
+  codeMirror:null,
+  updateCM:function () {
+    var cm = this.get('codeMirror');
+    if (this.get('readOnly')) {
+      cm.setValue((this.get('content.fileContent')||''));
+      return cm.setOption('readOnly',true);
+    }
+    var cmElement = $(cm.display.wrapper);
+    if (this.get('content.isLoaded')) {
+      cm.setOption('readOnly',false);
+      cmElement.removeClass('inactive');
+      cm.setValue((this.get('content.fileContent')||''));
+      cm.markClean();
+    } else {
+      cm.setOption('readOnly',true);
+      cmElement.addClass('inactive');
+    }
+  }.observes('codeMirror', 'content.didLoad'),
+  didInsertElement: function() {
+    var cm = CodeMirror.fromTextArea(this.get('element'),{
+      lineNumbers: true,
+      matchBrackets: true,
+      indentUnit: 4,
+      keyMap: "emacs"
+    });
+
+    $('.editor-container').resizable({
+      stop:function () {
+        cm.setSize(null, this.style.height);
+      },
+      resize: function() {
+        this.getElementsByClassName('CodeMirror')[0].style.height = this.style.height;
+        this.getElementsByClassName('CodeMirror-gutters')[0].style.height = this.style.height;
+      },
+      minHeight:215,
+      handles: {'s': '#sgrip' }
+    });
+
+    this.set('codeMirror',cm);
+    if (!this.get('readOnly')) {
+      cm.focus();
+      cm.on('change', Em.run.bind(this,this.editorDidChange));
+    }
+  },
+  editorDidChange:function () {
+    var pig_script = this.get('content');
+    if (pig_script.get('isLoaded')){
+      pig_script.set('fileContent',this.get('codeMirror').getValue());
+      this.get('codeMirror').markClean();
+    }
+  },
+  scriptDidChange:function () {
+    if (this.get('codeMirror').isClean() && this.get('content.isDirty')) {
+      this.get('codeMirror').setValue(this.get(('content.fileContent')||''));
+    }
+  }.observes('content.fileContent'),
+  willClearRender:function () {
+    this.get('codeMirror').toTextArea();
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/components/helpers-data.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/components/helpers-data.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/helpers-data.js
new file mode 100644
index 0000000..3fcb2f2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/helpers-data.js
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = [
+  {
+    'title':'Eval Functions',
+    'helpers':[
+      'AVG(%VAR%)',
+      'CONCAT(%VAR1%, %VAR2%)',
+      'COUNT(%VAR%)',
+      'COUNT_START(%VAR%)',
+      'IsEmpty(%VAR%)',
+      'DIFF(%VAR1%, %VAR2%)',
+      'MAX(%VAR%)',
+      'MIN(%VAR%)',
+      'SIZE(%VAR%)',
+      'SUM(%VAR%)',
+      'TOKENIZE(%VAR%, %DELIM%)'
+    ]
+  },
+  {
+    'title':'Relational Operators',
+    'helpers':[
+      'COGROUP %VAR% BY %VAR%',
+      'CROSS %VAR1%, %VAR2%;',
+      'DISTINCT %VAR%;',
+      'FILTER %VAR% BY %COND%',
+      'FLATTEN(%VAR%)',
+      'FOREACH %DATA% GENERATE %NEW_DATA%',
+      'FOREACH %DATA% {%NESTED_BLOCK%}',
+      'GROUP %VAR% BY %VAR%',
+      'GROUP %VAR% ALL',
+      'JOIN %VAR% BY ',
+      'LIMIT %VAR% %N%',
+      'ORDER %VAR% BY %FIELD%',
+      'SAMPLE %VAR% %SIZE%',
+      'SPLIT %VAR1% INTO %VAR2% IF %EXPRESSIONS%',
+      'UNION %VAR1%, %VAR2%'
+    ]
+  },
+  {
+    'title':'I/0',
+    'helpers':[
+      "LOAD '%FILE%';",
+      'DUMP %VAR%;',
+      'STORE %VAR% INTO %PATH%;'
+    ]
+  },
+  {
+    'title':'Debug',
+    'helpers':[
+      'EXPLAIN %VAR%;',
+      'ILLUSTRATE %VAR%;',
+      'DESCRIBE %VAR%;'
+    ]
+  },
+  {
+    'title':'HCatalog',
+    'helpers':[
+      "LOAD '%TABLE%' USING org.apache.hcatalog.pig.HCatLoader();"
+    ]
+  },
+  {
+    'title':'Math',
+    'helpers':[
+      'ABS(%VAR%)',
+      'ACOS(%VAR%)',
+      'ASIN(%VAR%)',
+      'ATAN(%VAR%)',
+      'CBRT(%VAR%)',
+      'CEIL(%VAR%)',
+      'COS(%VAR%)',
+      'COSH(%VAR%)',
+      'EXP(%VAR%)',
+      'FLOOR(%VAR%)',
+      'LOG(%VAR%)',
+      'LOG10(%VAR%)',
+      'RANDOM(%VAR%)',
+      'ROUND(%VAR%)',
+      'SIN(%VAR%)',
+      'SINH(%VAR%)',
+      'SQRT(%VAR%)',
+      'TAN(%VAR%)',
+      'TANH(%VAR%)'
+    ]
+  },
+  {
+    'title':'Tuple, Bag, Map Functions',
+    'helpers':[
+      'TOTUPLE(%VAR%)',
+      'TOBAG(%VAR%)',
+      'TOMAP(%KEY%, %VALUE%)',
+      'TOP(%topN%, %COLUMN%, %RELATION%)'
+    ]
+  },
+  {
+    'title':'String Functions',
+    'helpers':[
+      "INDEXOF(%STRING%, '%CHARACTER%', %STARTINDEX%)",
+      "LAST_INDEX_OF(%STRING%, '%CHARACTER%', %STARTINDEX%)",
+      "LOWER(%STRING%)",
+      "REGEX_EXTRACT(%STRING%, %REGEX%, %INDEX%)",
+      "REGEX_EXTRACT_ALL(%STRING%, %REGEX%)",
+      "REPLACE(%STRING%, '%oldChar%', '%newChar%')",
+      "STRSPLIT(%STRING%, %REGEX%, %LIMIT%)",
+      "SUBSTRING(%STRING%, %STARTINDEX%, %STOPINDEX%)",
+      "TRIM(%STRING%)",
+      "UCFIRST(%STRING%)",
+      "UPPER(%STRING%)"
+    ]
+  },
+  {
+    'title':'Macros',
+    'helpers':[
+      "IMPORT '%PATH_TO_MACRO%';"
+    ]
+  },
+  {
+    'title':'HBase',
+    'helpers':[
+      "LOAD 'hbase://%TABLE%' USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('%columnList%')",
+      "STORE %VAR% INTO 'hbase://%TABLE%' USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('%columnList%')"
+    ]
+  },
+  {
+    'title':'Python UDF',
+    'helpers':[
+      "REGISTER 'python_udf.py' USING jython AS myfuncs;"
+    ]
+  }
+]

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/components/jobProgress.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/components/jobProgress.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/jobProgress.js
new file mode 100644
index 0000000..24618ac
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/jobProgress.js
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.JobProgressComponent = Em.Component.extend({
+  job:null,
+  classNames:['progress'],
+  didInsertElement:function () {
+    this.update();
+  },
+  update:function () {
+    var progress = (!this.get('job.isTerminated'))?this.get('job.percentStatus'):100;
+    $(this.get('element')).find('.progress-bar').css('width',progress+'%');
+  }.observes('job.percentStatus'),
+  layout:Em.Handlebars.compile('<div {{bind-attr class=":progress-bar job.isTerminated:progress-bar-danger:progress-bar-success" }}role="progressbar"></div>')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/components/pigHelper.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/components/pigHelper.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/pigHelper.js
new file mode 100644
index 0000000..9e2f874
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/pigHelper.js
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var pigHelpers = require('./helpers-data');
+
+App.PigHelperComponent = Em.Component.extend({
+  layoutName: 'components/pigHelper',
+  helpers: pigHelpers,
+  editor: null,
+  actions:{
+    putToEditor:function (helper) {
+      var editor = this.get('editor');
+      var cursor = editor.getCursor();
+      var pos = this.findPosition(helper);
+
+      editor.replaceRange(helper, cursor, cursor);
+      editor.focus();
+
+      if (pos.length>1) {
+        editor.setSelection(
+          {line:cursor.line, ch:cursor.ch + pos[0]},
+          {line:cursor.line, ch:cursor.ch + pos[1]+1}
+        );
+      }
+
+      return false;
+    }
+  },
+  findPosition: function (curLine){
+    var pos= curLine.indexOf("%");
+    var posArr=[];
+    while(pos > -1) {
+      posArr.push(pos);
+      pos = curLine.indexOf("%", pos+1);
+    }
+    return posArr;
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/components/scriptListRow.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/components/scriptListRow.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/scriptListRow.js
new file mode 100644
index 0000000..2f5d9e6
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/scriptListRow.js
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptListRowComponent = Em.Component.extend({
+  tagName:'tr',
+  scriptJobs:function () {
+    var scriptId = this.get('script.id');
+    var scriptJobs = this.get('jobs').filter(function (job) {
+      return job.get('scriptId') == scriptId;
+    });
+    return scriptJobs;
+  }.property('jobs.content'),
+  scriptJobsIds: Ember.computed.mapBy('scriptJobs', 'id'),
+  currentJobId:Em.computed.max('scriptJobsIds'),
+  currentJob:function () {
+    var jobId = this.get('currentJobId');
+    var scriptJob = this.get('scriptJobs').filter(function (job) {
+      return job.get('id') == jobId;
+    });
+    return scriptJob.get('firstObject');
+  }.property('currentJobId','scriptJobs')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/components/tabControl.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/components/tabControl.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/tabControl.js
new file mode 100644
index 0000000..087d65b
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/components/tabControl.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.TabControlComponent = Em.Component.extend({
+  actions:{
+    popTab:function (name){
+      this.sendAction('popTab',name);
+    }
+  },
+  tagName:'li',
+  classNameBindings:['isActive:active','isJob:job','disabled:disabled'],
+  disabled:function () {
+    return !this.get('target');
+  }.property('target'),
+  isActive:function () {
+    return this.get('tab') == this.get('current');
+  }.property('tab','current'),
+  isJob:function () {
+    return !(this.get('tab') == 'history' || this.get('tab') == 'script');
+  }.property('tab'),
+  layout:Em.Handlebars.compile('{{yield}}{{#if isJob}}<button {{action \'popTab\' tab }} class="btn" ><i class="fa fa-close"></i></button>{{/if}}'),
+  tooltip:function () {
+    if (this.get('disabled')){
+      this.$().tooltip({title:'The script has been deleted and is no longer available.',placement:'bottom'});
+    }
+  }.on('didInsertElement')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js
deleted file mode 100644
index 4699ee4..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.EditController = Em.ObjectController.extend({
-  pigArgumentsPull: Em.A(),
-  isExec:false,
-  isRenaming:false,
-  actions:{
-    rename:function (opt) {
-      var changedAttributes = this.content.changedAttributes(),
-          controller = this;
-      if (opt==='ask') {
-        this.set('isRenaming',true);
-      };
-
-      if (opt==='cancel') {
-        this.content.rollback();
-        if (Em.isArray(changedAttributes.templetonArguments)) {
-          this.content.set('templetonArguments',changedAttributes.templetonArguments[1]);
-        }
-        this.set('isRenaming',false);
-      };
-
-      if (opt==='confirm') {
-        if (Em.isArray(changedAttributes.title)) {
-          this.content.save().then(function () {
-            controller.send('showAlert', {message:Em.I18n.t('editor.title_updated'),status:'success'});
-          });
-        }
-        this.set('isRenaming',false);
-      };
-
-    },
-    addArgument:function (arg) {
-      if (!arg) {
-        return false;
-      };
-      var pull = this.get('pigArgumentsPull');
-      if (Em.$.inArray(arg,pull)<0) {
-        pull.pushObject(arg);
-      } else {
-        this.send('showAlert', {'message': Em.I18n.t('scripts.alert.arg_present'), status:'info'});
-      }
-    },
-    removeArgument:function (arg) {
-      var index = this.pigArgumentsPull.indexOf(arg.toString());
-      this.pigArgumentsPull.removeAt(index);
-    },
-    execute: function (object, operation) {
-      var controller = this,
-          job,
-          sendAlert = function (status) {
-            var alerts = {success:Em.I18n.t('job.alert.job_started'), error:Em.I18n.t('job.alert.start_filed')};
-            return function (argument) {
-              controller.set('isExec',false);
-              var trace = null;
-              if (status=='error') {
-                trace = argument.responseJSON.trace;
-              }
-              controller.send('showAlert', {message:alerts[status],status:status,trace:trace});
-              if (status=='success') {
-                controller.transitionToRoute('job',job);
-              };
-            };
-          };
-
-      controller.set('isExec',true);
-
-      return Ember.RSVP.resolve(object.get('pigScript')).then(function (file) {
-        var savePromises = [file.save()];
-
-        job = controller.prepareJob(file, object, operation);
-
-        if (object.get('constructor.typeKey') === "script") {
-          savePromises.push(object.save());
-        };
-
-        return Ember.RSVP.all(savePromises).then(function () {
-          return job.save().then(sendAlert('success'),sendAlert('error'));
-        });
-      });
-    },
-  },
-  prepareJob:function (file, object, operation) {
-    var controller = this,
-        args = object.get('templetonArguments'),
-        parameters = this.get('pigParams.length') > 0,
-        pigParams = this.get('pigParams') || [],
-        fileContent = file.get('fileContent'),
-        config;
-
-    pigParams.forEach(function (param) {
-      var rgParam = new RegExp(param.param,'g');
-      fileContent = fileContent.replace(rgParam,param.value);
-    });
-    
-    if (operation === 'execute') {
-      config = {
-        templetonArguments: args,
-        title: object.get('title'),
-        forcedContent: (parameters)? fileContent:null,
-        pigScript: (!parameters)?file:null
-      };
-    } else if (operation === 'explain') {
-      config = {
-        templetonArguments:  '',
-        title: 'Explain: "' + object.get('title') + '"',
-        jobType: 'explain',
-        sourceFileContent: (parameters)? fileContent:null,
-        sourceFile: (!parameters)?file.get('id'):null,
-        forcedContent: 'explain -script ${sourceFile}'
-      }
-    } else {
-      config = {
-        templetonArguments: (!args.match(/-check/g))?args+(args?"\t":"")+'-check':args,
-        title: 'Syntax check: "' + object.get('title') + '"',
-        jobType:  'syntax_check',
-        forcedContent: (parameters)? fileContent:null,
-        pigScript: (!parameters)?file:null
-      }
-    };
-    
-    if (object.get('constructor.typeKey') === 'script'){
-      config.scriptId = object.get('id');
-    } else {
-      config.scriptId = (operation != 'explain')?object.get('scriptId'):null;
-    };
-
-    return this.store.createRecord('job',config);
-  },
-  /*
-   *Is script or scritp file is dirty.
-   * @return {boolean}
-   */
-  scriptDirty:function () {
-    return this.get('content.isDirty') || this.get('content.pigScript.isDirty');
-  }.property('content.pigScript.isDirty','content.isDirty'),
-
-  /**
-   * Is script is in error state.
-   * @return {boolean}
-   */
-  scriptError:function () {
-    return this.get('content.isError');
-  }.property('content.isError'),
-
-  /*
-    Gets script arguments array from pigArgumentsPull
-    and write to model as string
-  */
-  pigArgToString:function (controller,observer) {
-    var args = controller.get('pigArgumentsPull');
-    var oldargs = (this.get('content.templetonArguments'))?this.get('content.templetonArguments').w():[];
-    if (args.length != oldargs.length) {
-      this.set('content.templetonArguments',args.join('\t'));
-    };
-  }.observes('pigArgumentsPull.@each'),
-
-  /*
-    get script arguments string from model
-    and write to pigArgumentsPull as array
-  */
-  pigArgToArray:function (controller,observer) {
-    var args =  controller.get(observer);
-    if (args && args.length > 0){
-      controller.set('pigArgumentsPull',args.w());
-    }
-  }.observes('content.templetonArguments'),
-
-  /**
-   * available UDFs
-   * @return {App.Udf} promise
-   */
-  ufdsList:function () {
-    return this.store.find('udf');
-  }.property('udf'),
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/errorLog.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/errorLog.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/errorLog.js
index c4ffe8c..7d00145 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/errorLog.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/errorLog.js
@@ -19,5 +19,5 @@
 var App = require('app');
 
 App.PigErrorLogController = Ember.ObjectController.extend({
-  errorLog: null,
+  errorLog: 'No trace'
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js
deleted file mode 100644
index cc5d770..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.JobResultsController = Em.ObjectController.extend({
-  getOutputProxy:function (output) {
-    var self = this,
-        promise,
-        result;
-
-    var host = this.store.adapterFor('application').get('host');
-    var namespace = this.store.adapterFor('application').get('namespace');
-    var jobId = this.get('content.id');
-    var url = [host, namespace,'jobs',jobId, 'results',output].join('/');
-
-    promise = new Ember.RSVP.Promise(function(resolve,reject){
-      return Em.$.getJSON(url).then(function (stdoutFile) {
-        resolve(stdoutFile.file);
-      },function (error) {
-        var responseText = JSON.parse(error.responseText);
-        self.send('showAlert', {'message': Em.I18n.t('job.alert.'+output+'_error',
-          {status:responseText.status, message:responseText.message}), status:'error', trace: responseText.trace});
-      })
-    });
-
-    return Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
-      promise: promise
-    });
-  },
-  checkStatus:function (argument) {
-    return (this.get('content.status')=='COMPLETED')?true:false;
-  },
-  stdout:function() {
-    return (this.checkStatus())?this.getOutputProxy('stdout'):null;
-  }.property(),
-  stderr:function() {
-    return (this.checkStatus())?this.getOutputProxy('stderr'):null;
-  }.property(),
-  exitcode:function() {
-    return (this.checkStatus())?this.getOutputProxy('exit'):null;
-  }.property()
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmAway.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmAway.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmAway.js
new file mode 100644
index 0000000..c231948
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmAway.js
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ConfirmAwayController = Ember.ObjectController.extend({
+  needs:['pig'],
+  waitingTransition:null,
+  actions:{
+    confirm:function () {
+      var transition = this.get('content');
+      var script = this.get('controllers.pig.activeScript');
+      this.get('controllers.pig').send('saveScript',script,this.saveCallback.bind(this));
+      this.set('waitingTransition',transition);
+    },
+    discard:function () {
+      var script = this.get('controllers.pig.activeScript');
+      var filePromise = script.get('pigScript');
+      var transition = this.get('content');
+      this.set('waitingTransition',transition);
+      filePromise.then(function (file) {
+        script.rollback();
+        file.rollback();
+        this.get('waitingTransition').retry();
+      }.bind(this))
+    }
+  },
+  saveCallback:function(response){
+    this.get('waitingTransition').retry();
+    this.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_saved',{title: response[1].get('title')}),status:'success'});
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmDelete.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmDelete.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmDelete.js
new file mode 100644
index 0000000..a9bc278
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/confirmDelete.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ConfirmDeleteController = Ember.ObjectController.extend({
+  needs:['pig'],
+  actions:{
+    confirm:function () {
+      this.get('controllers.pig').send('confirmdelete',this.get('content'));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createScript.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createScript.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createScript.js
new file mode 100644
index 0000000..f0781d9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createScript.js
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.CreateScriptController = Ember.ObjectController.extend({
+  needs:['pigScripts'],
+  filePath:'',
+  clearFilePath:function () {
+    this.set('didInsertTtle',false);
+    this.set('filePath','');
+  }.observes('content'),
+  actions:{
+    confirm:function () {
+      var title = this.get('content.title');
+      if (!title) {
+        this.set('error', Em.I18n.t('scripts.modal.error_empty_title'));
+        return;
+      }
+      this.get('controllers.pigScripts').send('confirmcreate',this.get('content'),this.get('filePath'));
+    },
+    cancel:function (script) {
+      this.get('content').deleteRecord();
+    }
+  },
+  didInsertTtle:false,
+  titleError:function () {
+    var title = this.get('content.title');
+
+    if (!title && this.get('didInsertTtle')) {
+      return Em.I18n.t('scripts.modal.error_empty_title');
+    } else {
+      this.set('didInsertTtle',true);
+    }
+    return '';
+  }.property('content.title')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createUdf.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createUdf.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createUdf.js
new file mode 100644
index 0000000..3982ec7
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/createUdf.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.CreateUdfController = Ember.ObjectController.extend({
+  needs:['pigUdfs'],
+  actions:{
+    confirm:function () {
+      this.get('controllers.pigUdfs').send('createUdf',this.get('content'),this.get('filePath'));
+    },
+    cancel:function () {
+      this.get('content').deleteRecord();
+    }
+  },
+  udfInvalid:function (argument) {
+    return !this.get('content.name') || !this.get('content.path');
+  }.property('content.name','content.path')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/deleteJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/deleteJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/deleteJob.js
new file mode 100644
index 0000000..83cf447
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/deleteJob.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.DeleteJobController = Ember.ObjectController.extend({
+  needs:['script'],
+  actions:{
+    confirm:function () {
+      this.get('controllers.script').send('deleteJob',this.get('content'));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/gotoCopy.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/gotoCopy.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/gotoCopy.js
new file mode 100644
index 0000000..a352184
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/gotoCopy.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.GotoCopyController = Ember.ObjectController.extend({
+  needs:['pig'],
+  actions:{
+    confirm:function () {
+      this.transitionToRoute('script.edit',this.get('content.id'));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/logDownload.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/logDownload.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/logDownload.js
new file mode 100644
index 0000000..2603439
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/logDownload.js
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.LogDownloadController = Ember.ObjectController.extend(App.FileHandler,{
+  jobLogsLoader:function (output) {
+    var jobId = this.get('content.id');
+    var url = ['jobs',jobId, 'results','stderr'].join('/');
+
+    return this.fileProxy(url);
+  }.property('content'),
+
+  suggestedFilename: function() {
+    return this.get("content.jobId").toLowerCase().replace(/\W+/g, "_") + '_logs.txt';
+  }.property("content.jobId"),
+
+  jobLogs:function () {
+    return this.get('jobLogsLoader.content.fileContent');
+  }.property("content","jobLogsLoader.isPending"),
+
+  actions:{
+    download:function () {
+      return this.downloadFile(this.get("jobLogs"), this.get("suggestedFilename"));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
index 85411af..9bb2950 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
@@ -18,5 +18,44 @@
 
 var App = require('app');
 
-App.PigModalController = Ember.ObjectController.extend({ 
+App.PigModalComponent = Ember.Component.extend({
+  didClose:'removeModal',
+  size:'',
+  large:function () {
+    return this.get('size') =='lg';
+  }.property('size'),
+  small:function () {
+    return this.get('size') =='sm';
+  }.property('size'),
+  layoutName:'modal/modalLayout',
+  actions: {
+    ok: function() {
+      this.$('.modal').modal('hide');
+      this.sendAction('ok');
+    },
+    cancel:function () {
+      this.$('.modal').modal('hide');
+      this.sendAction('close');
+    },
+    option:function () {
+      this.$('.modal').modal('hide');
+      this.sendAction('option');
+    }
+  },
+  keyUp:function (e) {
+    if (e.keyCode == 27) {
+      this.sendAction('close');
+    }
+  },
+  show: function() {
+    var modal = this.$('.modal').modal();
+    modal.off('hidden.bs.modal');
+    modal.off('shown.bs.modal');
+    modal.on('shown.bs.modal',function () {
+      this.find('input').first().focus();
+    }.bind(modal));
+    modal.on('hidden.bs.modal', function() {
+      this.sendAction('didClose');
+    }.bind(this));
+  }.on('didInsertElement')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/resultsDownload.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/resultsDownload.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/resultsDownload.js
new file mode 100644
index 0000000..81b4a50
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/resultsDownload.js
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ResultsDownloadController = Ember.ObjectController.extend(App.FileHandler,{
+  jobResultsLoader:function (output) {
+    var jobId = this.get('content.id');
+    var url = ['jobs',jobId, 'results','stdout'].join('/');
+
+    return this.fileProxy(url);
+  }.property('content'),
+
+  suggestedFilename: function() {
+    return this.get("content.jobId").toLowerCase().replace(/\W+/g, "_") + '_results.txt';
+  }.property("content.jobId"),
+
+  jobResults:function () {
+    return this.get('jobResultsLoader.content.fileContent');
+  }.property("content","jobResultsLoader.isPending"),
+
+  actions:{
+    download:function () {
+      return this.downloadFile(this.get("jobResults"), this.get("suggestedFilename"));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/page.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/page.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/page.js
new file mode 100644
index 0000000..f8a7534
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/page.js
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PageController = Ember.ObjectController.extend({
+  currentPage: Ember.computed.alias('parentController.page'),
+
+  isActive:function() {
+    return this.get('number') === this.get('currentPage');
+  }.property('number', 'currentPage')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
index ed04971..1a1ac4d 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
@@ -19,8 +19,85 @@
 var App = require('app');
 
 App.PigController = Em.ArrayController.extend({
+  needs:['scriptEdit'],
   category: 'scripts',
-  openScripts: function() {
-    return this.get('content').filterBy('opened',true);
-  }.property('content.@each.opened')
+  actions:{
+    closeScript:function () {
+      this.transitionToRoute('pig.scripts');
+    },
+    saveScript: function (script,onSuccessCallback) {
+      var onSuccess = onSuccessCallback || function(model){
+          //this.set('disableScriptControls',false);
+          this.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_saved',{title: script.get('title')}),status:'success'});
+        }.bind(this),
+        onFail = function(error){
+          var trace = null;
+          if (error && error.responseJSON.trace)
+            trace = error.responseJSON.trace;
+          this.send('showAlert', {'message':Em.I18n.t('scripts.alert.save_error'),status:'error',trace:trace});
+        }.bind(this);
+
+      return script.get('pigScript').then(function(file){
+        return Ember.RSVP.all([file.save(),script.save()]).then(onSuccess,onFail);
+      },onFail);
+    },
+    deletescript:function (script) {
+      return this.send('openModal','confirmDelete',script);
+    },
+    confirmdelete:function (script) {
+      var onSuccess = function(model){
+            this.transitionToRoute('pig.scripts');
+            this.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_deleted',{title : model.get('title')}),status:'success'});
+          }.bind(this);
+      var onFail = function(error){
+            var trace = null;
+            if (error && error.responseJSON.trace)
+              trace = error.responseJSON.trace;
+            this.send('showAlert', {'message':Em.I18n.t('scripts.alert.delete_failed'),status:'error',trace:trace});
+          }.bind(this);
+      script.deleteRecord();
+      return script.save().then(onSuccess,onFail);
+    },
+    copyScript:function (script) {
+      script.get('pigScript').then(function (file) {
+
+        var newScript = this.store.createRecord('script',{
+          title:script.get('title')+' (copy)',
+          templetonArguments:script.get('templetonArguments')
+        });
+
+        newScript.save().then(function (savedScript) {
+          savedScript.get('pigScript').then(function (newFile) {
+            newFile.set('fileContent',file.get('fileContent'));
+            newFile.save().then(function () {
+              this.send('showAlert', {'message':script.get('title') + ' is copied.',status:'success'});
+              if (this.get('activeScript')) {
+                this.send('openModal','gotoCopy',savedScript);
+              }
+            }.bind(this));
+          }.bind(this));
+        }.bind(this));
+      }.bind(this));
+    }
+  },
+
+  activeScriptId:null,
+
+  disableScriptControls:Em.computed.alias('controllers.scriptEdit.isRenaming'),
+
+  activeScript:function () {
+    return (this.get('activeScriptId'))?this.get('content').findBy('id',this.get('activeScriptId').toString()):null;
+  }.property('activeScriptId',"content.[]"),
+
+  /*
+   *Is script or script file is dirty.
+   * @return {boolean}
+   */
+  scriptDirty:function () {
+    return this.get('activeScript.isDirty') || this.get('activeScript.pigScript.isDirty');
+  }.property('activeScript.pigScript.isDirty','activeScript.isDirty'),
+
+  saveEnabled:function () {
+    return this.get('scriptDirty') && !this.get('disableScriptControls');
+  }.property('scriptDirty','disableScriptControls')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigAlert.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigAlert.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigAlert.js
new file mode 100644
index 0000000..65273a9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigAlert.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigAlertController = Ember.ArrayController.extend({
+  content:Ember.A(),
+  needs: ['pigErrorLog'],
+  actions:{
+    removeAlertObject:function (alert) {
+      this.content.removeObject(alert)
+    },
+    showErrorLog:function (context) {
+      errorLogController = this.get('controllers.pigErrorLog');
+      errorLogController.set('errorLog', context.trace);
+      this.transitionToRoute('pig.errorLog');
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
index 433733e..bffcccd 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
@@ -18,11 +18,23 @@
 
 var App = require('app');
 
-App.PigHistoryController = Em.ArrayController.extend({
-  content: [],
-  jobs: function() {
-    return this.get('content').filter(function(job, index, enumerable){
-      return job.get('status') != 'SUBMIT_FAILED';
-    });
-  }.property('content.@each.status')
+App.PigHistoryController = Em.ArrayController.extend(App.Pagination,{
+  needs:['pig'],
+  sortProperties: ['dateStarted'],
+  sortAscending: false,
+  scriptIds:Em.computed.mapBy('controllers.pig.content','id'),
+  actions:{
+    logsPopup:function (job) {
+      this.send('openModal','logDownload',job);
+    },
+    resultsPopup:function (job) {
+      this.send('openModal','resultsDownload',job);
+    },
+    goToScript:function (id) {
+      this.transitionToRoute('script.edit',id);
+    },
+    deleteJob:function (job) {
+      this.send('openModal','deleteJob',job);
+    }
+  }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js
deleted file mode 100644
index 1ae96f8..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-
-App.JobController = App.EditController.extend({
-  needs:['poll'],
-  isJob:true,
-  category:'edit',
-  actions:{
-    returnToOriginal: function (job) {
-      this.transitionToRoute('pig.scriptEdit', job.get('scriptId'));
-    },
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js
deleted file mode 100644
index 3be1301..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptEditController = App.EditController.extend({
-  needs:['pig'],
-  isScript:true,
-  pigParams:Em.A(),
-
-  /*
-    Updates nav title when renaming script.
-   */
-  updateNavTitle:function (controller) {
-    var pigC = controller.get('controllers.pig')
-    if (!($.inArray(pigC.get('category'),['udfs','scripts','history'])>=0)){
-      pigC.set('category',this.get('content.name'));
-    }
-  }.observes('content.name'),
-
-  /*
-    Observes params (%VAR%) in sript file 
-    and updates pigParams object as they changes. 
-   */
-  pigParamsMatch:function (controller) {
-    var editorContent = this.get('content.pigScript').then(function(data) {
-      editorContent = data.get('fileContent');
-      if (editorContent) {
-            var match_var = editorContent.match(/\%\w+\%/g);
-            if (match_var) {
-              var oldParams = controller.pigParams;
-              controller.set('pigParams',[]);
-              match_var.forEach(function (param) {
-                var suchParams = controller.pigParams.filterProperty('param',param);
-                if (suchParams.length == 0){
-                  var oldParam = oldParams.filterProperty('param',param);
-                  var oldValue = oldParam.get('firstObject.value');
-                  controller.pigParams.pushObject(Em.Object.create({param:param,value:oldValue,title:param.replace(/%/g,'')}));
-                }
-              });
-            } else {
-              controller.set('pigParams',[]);
-            }
-          };
-    }, function(reason) {
-      var trace = null;
-      if (reason.responseJSON.trace)
-        trace = reason.responseJSON.trace;
-      controller.send('showAlert', {'message':Em.I18n.t('scripts.alert.file_not_found',{title: 'Error'}),status:'error',trace:trace});
-    });
-  }.observes('content.pigScript.fileContent'),
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js
deleted file mode 100644
index f02f9f7..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptEditResultsController = Em.ObjectController.extend({
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js
deleted file mode 100644
index 0422de2..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptListController = Em.ArrayController.extend({
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScripts.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScripts.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScripts.js
new file mode 100644
index 0000000..6c39c67
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScripts.js
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptsController = Em.ArrayController.extend(App.Pagination,{
+  sortProperties: ['dateCreatedUnix'],
+  sortAscending: false,
+  needs:['pig'],
+  actions:{
+    createScript:function () {
+      var newScript = this.store.createRecord('script');
+      return this.send('openModal', 'createScript', newScript);
+    },
+    confirmcreate:function (script,filePath) {
+      var _this = this;
+      var bnd = Em.run.bind;
+
+      if (filePath) {
+        try {
+          var file = this.store.createRecord('file',{
+            id:filePath,
+            fileContent:''
+          })
+        } catch (e) {
+          return this.createScriptError(script,e);
+        }
+        return file.save()
+          .then(function(file){
+              script.set('pigScript',file);
+              script.save().then(bnd(_this,_this.createScriptSuccess),bnd(_this,_this.createScriptError,script));
+            },
+            function () {
+              file.deleteRecord();
+              _this.store.find('file', filePath).then(function(file) {
+                _this.send('showAlert', {message:Em.I18n.t('scripts.alert.file_exist_error'),status:'success'});
+                script.set('pigScript',file);
+                script.save().then(bnd(_this,_this.createScriptSuccess),bnd(_this,_this.createScriptError,script));
+              },bnd(_this,_this.createScriptError,script));
+          });
+      } else {
+          script.save().then(bnd(this,this.createScriptSuccess),bnd(this,this.createScriptError,script));
+      }
+    },
+    deletescript:function (script) {
+      this.get('controllers.pig').send('deletescript',script);
+    },
+    copyScript:function (script) {
+      this.get('controllers.pig').send('copyScript',script);
+    }
+  },
+
+  createScriptSuccess:function (script,s) {
+    this.send('showAlert', { message:Em.I18n.t('scripts.alert.script_created',{title:script.get('title')}), status:'success' });
+    this.transitionToRoute('script.edit',script);
+  },
+  createScriptError:function (script,error) {
+    var trace = null;
+    trace = (error.responseJSON)?error.responseJSON.trace:error.message;
+
+    script.deleteRecord();
+
+    this.send('showAlert', {message:Em.I18n.t('scripts.alert.create_failed'),status:'error',trace:trace});
+  },
+
+  jobs:function () {
+    return this.store.find('job');
+  }.property()
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
index e855e04..da41427 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
@@ -18,6 +18,50 @@
 
 var App = require('app');
 
-App.PigUdfsController = Em.ArrayController.extend({
-  
+App.PigUdfsController = Em.ArrayController.extend(App.Pagination,{
+  actions:{
+    createUdfModal:function () {
+      return this.send('openModal','createUdf',this.store.createRecord('udf'));
+    },
+    createUdf:function (udf) {
+      return udf.save().then(this.onCreateSuccess.bind(this),this.onCreateFail.bind(this));
+    },
+    deleteUdf:function(udf){
+      udf.deleteRecord();
+      return udf.save().then(this.onDeleteSuccess.bind(this),this.onDeleteFail.bind(this));
+    }
+  },
+  onCreateSuccess:function (model) {
+    this.send('showAlert', {
+      message: Em.I18n.t('udfs.alert.udf_created',{name : model.get('name')}),
+      status:'success'
+    });
+  },
+  onCreateFail:function (error) {
+    var trace = null;
+    if (error && error.responseJSON.trace) {
+      trace = error.responseJSON.trace;
+    }
+    this.send('showAlert', {
+      message:Em.I18n.t('udfs.alert.create_failed'),
+      status:'error',trace:trace
+    });
+  },
+  onDeleteSuccess: function(model){
+    this.send('showAlert', {
+      message: Em.I18n.t('udfs.alert.udf_deleted',{name : model.get('name')}),
+      status:'success'
+    });
+  },
+  onDeleteFail:function(error){
+    var trace = null;
+    if (error && error.responseJSON.trace)
+      trace = error.responseJSON.trace;
+
+    this.send('showAlert', {
+      message: Em.I18n.t('udfs.alert.delete_failed'),
+      status:'error',
+      trace:trace
+    });
+  }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js
deleted file mode 100644
index c5a1d27..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PollController = Ember.ObjectController.extend({
-  actions:{
-    killjob:function (job) {
-      var self = this;
-      job.kill(function () {
-        job.reload();
-        self.send('showAlert', {'message': Em.I18n.t('job.alert.job_killed',{title:self.get('title')}), status:'info'});
-      },function (reason) {
-        var trace = null;
-        if (reason && reason.responseJSON.trace)
-          trace = reason.responseJSON.trace;
-        self.send('showAlert', {'message': Em.I18n.t('job.alert.job_kill_error'), status:'error', trace:trace});
-      });
-    },
-  },
-  pollster:Em.Object.create({
-    job:null,
-    start: function(job){
-      this.stop();
-      this.set('job',job);
-      this.timer = setInterval(this.onPoll.bind(this), 5000);
-      console.log('START polling. Job: ',this.get('job.id'),'. Timer: ',this.timer)
-    },
-    stop: function(){
-      this.set('job',null);
-      clearInterval(this.timer);
-      console.log('STOP polling. Job: ',this.get('job.id'),'. Timer: ',this.timer)
-    },
-    onPoll: function() {
-      if (this.job.get('needsPing')) {
-        console.log('DO polling. Job: ',this.get('job.id'),'. Timer: ', this.timer)
-        this.job.reload();
-      } else {
-        console.log('END polling. Job: ',this.get('job.id'),'. Timer: ',this.timer)
-        this.stop();
-      };
-    }
-  })
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/script.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/script.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/script.js
new file mode 100644
index 0000000..1aced02
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/script.js
@@ -0,0 +1,117 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptController = Em.ObjectController.extend({
+  actions :{
+    deactivateJob:function (jobId) {
+      var rejected = this.get('activeJobs').rejectBy('id',jobId);
+      this.set('activeJobs',rejected);
+      if (!this.get('controllers.pig.activeScript')) {
+        this.transitionToRoute('pig.history');
+      }
+      else if (this.get('activeTab') == jobId) {
+        this.transitionToRoute('script.edit',this.get('controllers.pig.activeScript.id'));
+      }
+    },
+    deleteJob:function (job) {
+      job.deleteRecord();
+      job.save().then(this.deleteJobSuccess.bind(this),Em.run.bind(this,this.deleteJobFailed,job));
+      this.get('activeJobs').removeObject(job);
+    }
+  },
+
+  deleteJobSuccess:function (data) {
+    this.send('showAlert', {message:Em.I18n.t('job.alert.job_deleted'),status:'info'})
+  },
+  deleteJobFailed:function (job,error) {
+    var trace = (error.responseJSON)?error.responseJSON.trace:null;
+    job.rollback();
+    this.send('showAlert', {message:Em.I18n.t('job.alert.delete_filed'),status:'error',trace:trace});
+  },
+
+  needs:['pig'],
+
+  activeTab: 'script',
+
+  isScript:true,
+
+  activeJobs:Em.A(),
+  activeJobsIds:Em.computed.mapBy('activeJobs','id'),
+
+  staticTabs:function () {
+    return [
+      {label:'Script',name:'script',url:'script.edit',target:this.get('controllers.pig.activeScript.id')},
+      {label:'History',name:'history',url:'script.history',target:this.get('controllers.pig.activeScript.id')},
+    ];
+  }.property('controllers.pig.activeScript.id'),
+
+  jobTabs:function () {
+    var jobTabs = [];
+    this.get('activeJobs').forEach(function (job) {
+      jobTabs.push({label:job.get('title') + ' - ' + job.get('status').decamelize().capitalize(), name:job.get('id'),url:'script.job',target:job.get('id')})
+    });
+    return jobTabs;
+  }.property('activeJobs.[]','activeJobs.@each.status'),
+
+  tabs:Em.computed.union('staticTabs','jobTabs'),
+
+  pollster:Em.Object.create({
+    jobs:[],
+    timer:null,
+    start: function(jobs){
+      this.stop();
+      this.set('jobs',jobs);
+      this.onPoll();
+    },
+    stop: function(){
+      Em.run.cancel(this.get('timer'))
+    },
+    onPoll: function() {
+      this.get('jobs').forEach(function (job) {
+        if (job.get('needsPing')) {
+          job.reload();
+        } else {
+          this.jobs.removeObject(job)
+        };
+      }.bind(this));
+
+      if (this.get('jobs.length') > 0) {
+        this.set('timer', Ember.run.later(this, function() {
+          this.onPoll();
+        }, 3000));
+      }
+    }
+  }),
+
+  pollingWatcher:function () {
+    var pollster = this.get('pollster');
+    if (this.get('activeJobs.length') > 0) {
+      pollster.start(this.get('activeJobs').copy());
+    } else {
+      pollster.stop();
+    }
+  }.observes('activeJobs.@each'),
+
+  activeJobsWatcher:function () {
+    if (this.get('activeJobs.firstObject.scriptId') != this.get('controllers.pig.activeScript.id')) {
+      this.set('activeJobs',[]);
+    };
+  }.observes('controllers.pig.activeScript.id')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptEdit.js
new file mode 100644
index 0000000..816eb38
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptEdit.js
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptEditController = Em.ObjectController.extend({
+  needs:['script'],
+  pigParams: Em.A(),
+  isExec:false,
+  isRenaming:false,
+  titleWarn:false,
+  tmpArgument:'',
+  editor:null,
+
+  handleRenaming:function () {
+    if (this.get('content.title')) {
+      this.set('titleWarn',false);
+    }
+  }.observes('content.title','isRenaming'),
+
+  pigParamsMatch:function (controller) {
+    editorContent = this.get('content.pigScript.fileContent');
+    if (editorContent) {
+      var match_var = editorContent.match(/\%\w+\%/g);
+      if (match_var) {
+        var oldParams = controller.pigParams;
+        controller.set('pigParams',[]);
+        match_var.forEach(function (param) {
+          var suchParams = controller.pigParams.filterProperty('param',param);
+          if (suchParams.length == 0){
+            var oldParam = oldParams.filterProperty('param',param);
+            var oldValue = oldParam.get('firstObject.value');
+            controller.pigParams.pushObject(Em.Object.create({param:param,value:oldValue,title:param.replace(/%/g,'')}));
+          }
+        });
+      } else {
+        controller.set('pigParams',[]);
+      }
+    } else {
+      controller.set('pigParams',[]);
+    };
+  }.observes('content.pigScript.fileContent','content.id'),
+
+
+  oldTitle:'',
+  actions: {
+    rename:function (opt) {
+      var changedAttributes = this.get('content').changedAttributes()
+
+      if (opt==='ask') {
+        this.set('oldTitle',this.get('content.title'));
+        this.set('isRenaming',true);
+      };
+
+      if (opt==='cancel') {
+        this.set('content.title',this.get('oldTitle'));
+        this.set('oldTitle','');
+        this.set('isRenaming',false);
+      };
+
+      if (opt==='confirm') {
+        if (Em.isArray(changedAttributes.title) && this.get('content.title')) {
+          this.get('content').save().then(function () {
+            this.send('showAlert', {message:Em.I18n.t('editor.title_updated'),status:'success'});
+          }.bind(this));
+        }
+        this.set('oldTitle','');
+        this.set('isRenaming',false);
+      }
+    },
+    addArgument:function () {
+      var arg = this.get('tmpArgument');
+      if (!arg) {
+        return false;
+      }
+      var pull = this.get('content.argumentsArray');
+      if (Em.$.inArray(arg,pull)<0) {
+        pull.pushObject(arg);
+        this.set('content.argumentsArray',pull);
+        this.set('tmpArgument','');
+      } else {
+        this.send('showAlert', {'message': Em.I18n.t('scripts.alert.arg_present'), status:'info'});
+      }
+    },
+    removeArgument:function (arg) {
+      var removed = this.get('content.argumentsArray').removeObject(arg);
+      this.set('content.argumentsArray',removed);
+    },
+    execute: function (script, operation) {
+      var executeMethod = {
+        'execute':this.prepareExecute,
+        'explain':this.prepareExplain,
+        'syntax_check':this.prepareSyntaxCheck
+      };
+
+      this.set('isExec',true);
+
+      return Ember.RSVP.resolve(script.get('pigScript'))
+        .then(function (file) {
+          return Ember.RSVP.all([file.save(),script.save()]);
+        })
+        .then(executeMethod[operation].bind(this))
+        .then(this.executeSuccess.bind(this), this.executeError.bind(this))
+        .finally(Em.run.bind(this,this.set,'isExec',false));
+    }
+  },
+
+  executeSuccess:function (job) {
+    this.send('showAlert', {message:Em.I18n.t('job.alert.job_started'),status:'success'});
+    if (this.target.isActive('script.edit')) {
+      Em.run.next(this,this.transitionToRoute,'script.job',job);
+    }
+  },
+
+  executeError:function (error) {
+    var trace = (error.responseJSON)?error.responseJSON.trace:null;
+    this.send('showAlert', {message:Em.I18n.t('job.alert.start_filed'),status:'error',trace:trace});
+  },
+
+  prepareExecute:function (data) {
+    var file = data[0], script = data[1], pigParams = this.get('pigParams') || [], fileContent = file.get('fileContent');
+
+    pigParams.forEach(function (param) {
+      var rgParam = new RegExp(param.param,'g');
+      fileContent = fileContent.replace(rgParam,param.value);
+    });
+
+    var job = this.store.createRecord('job',{
+      scriptId: script.get('id'),
+      templetonArguments: script.get('templetonArguments'),
+      title: script.get('title'),
+      forcedContent: (pigParams.length > 0)? fileContent:null,
+      pigScript: (pigParams.length == 0)?file:null
+    });
+
+    return job.save();
+  },
+  prepareExplain:function (data) {
+    var file = data[0], script = data[1], pigParams = this.get('pigParams') || [], fileContent = file.get('fileContent');
+
+    pigParams.forEach(function (param) {
+      var rgParam = new RegExp(param.param,'g');
+      fileContent = fileContent.replace(rgParam,param.value);
+    });
+
+    var job = this.store.createRecord('job',{
+      scriptId: script.get('id'),
+      templetonArguments: '',
+      title: 'Explain: "' + script.get('title') + '"',
+      jobType: 'explain',
+      sourceFileContent: (pigParams.length > 0)? fileContent:null,
+      sourceFile: (pigParams.length == 0)?file.get('id'):null,
+      forcedContent: 'explain -script ${sourceFile}'
+    });
+
+    return job.save();
+  },
+  prepareSyntaxCheck:function (data) {
+    var file = data[0], script = data[1], pigParams = this.get('pigParams') || [], fileContent = file.get('fileContent'), args = script.get('templetonArguments');
+
+    pigParams.forEach(function (param) {
+      var rgParam = new RegExp(param.param,'g');
+      fileContent = fileContent.replace(rgParam,param.value);
+    });
+
+    var job = this.store.createRecord('job',{
+      scriptId: script.get('id'),
+      templetonArguments: (!args.match(/-check/g))?args+(args?"\t":"")+'-check':args,
+      title: 'Syntax check: "' + script.get('title') + '"',
+      jobType:  'syntax_check',
+      forcedContent: (pigParams.length > 0)? fileContent:null,
+      pigScript: (pigParams.length == 0)?file:null
+    });
+
+    return job.save();
+  },
+
+  /**
+   * Is script is in error state.
+   * @return {boolean}
+   */
+  scriptError:function () {
+    return this.get('content.isError');
+  }.property('content.isError'),
+
+  /**
+   * available UDFs
+   * @return {App.Udf} promise
+   */
+  ufdsList:function () {
+    return this.store.find('udf');
+  }.property('udf')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptHistory.js
new file mode 100644
index 0000000..db0cd85
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptHistory.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptHistoryController = Em.ArrayController.extend(App.Pagination,{
+  sortProperties: ['dateStarted'],
+  sortAscending: false,
+  actions:{
+    logsPopup:function (job) {
+      this.send('openModal','logDownload',job);
+    },
+    resultsPopup:function (job) {
+      this.send('openModal','resultsDownload',job);
+    },
+    deleteJob:function (job) {
+      this.send('openModal','deleteJob',job);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptJob.js
new file mode 100644
index 0000000..8cd4fdc
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/scriptJob.js
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptJobController = Em.ObjectController.extend(App.FileHandler,{
+  scriptContents:function () {
+    var promise = new Ember.RSVP.Promise(function(resolve,reject){
+      return this.get('content.pigScript').then(function (pigScript) {
+        return resolve(pigScript);
+      },function (error) {
+        var response = (error.responseJSON)?error.responseJSON:{};
+        reject(response.message);
+        if (error.status != 404) {
+          controller.send('showAlert', {'message': Em.I18n.t('job.alert.promise_error',
+            {status:response.status, message:response.message}), status:'error', trace: response.trace});
+        }
+      }.bind(this));
+    }.bind(this));
+    return Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
+      promise: promise
+    });
+  }.property('content'),
+
+  jobResults:function (output) {
+    var jobId = this.get('content.id');
+    var url = ['jobs', jobId, 'results', 'stdout'].join('/');
+
+    return this.fileProxy(url);
+  }.property('content'),
+
+  jobLogs:function (output) {
+    var jobId = this.get('content.id');
+    var url = ['jobs', jobId, 'results', 'stderr'].join('/');
+
+    return this.fileProxy(url);
+  }.property('content'),
+
+  suggestedFilenamePrefix: function() {
+    return this.get("content.jobId").toLowerCase().replace(/\W+/g, "_");
+  }.property("content.jobId"),
+
+  actions:{
+    download:function (opt) {
+      var file = (opt == 'results')?'jobResults.content.fileContent':'jobLogs.content.fileContent';
+      var suffix = (opt == 'results')?'_results.txt':'_logs.txt';
+      return this.downloadFile(this.get(file), this.get("suggestedFilenamePrefix")+suffix);
+    }
+  }
+});


[07/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js
deleted file mode 100644
index 3fd3138..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigUtilAlertController = Ember.ArrayController.extend({
-  content:Ember.A(),
-  needs: ['pigErrorLog'],
-  actions:{
-    removeAlertObject:function (alert) {
-      this.content.removeObject(alert)
-    },
-    showErrorLog:function (content) {
-      errorLogController = this.get('controllers.pigErrorLog');
-      errorLogController.set('errorLog', content[0].trace);
-      this.transitionToRoute('pig.errorLog');
-    },
-  },
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
index 2431d26..299b4c2 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-var App = require('app');
+window.App = require('app');
 
 App.ApplicationAdapter = DS.RESTAdapter.extend({
   namespace: App.getNamespaceUrl(),
@@ -28,11 +28,18 @@ App.ApplicationAdapter = DS.RESTAdapter.extend({
 App.FileAdapter = App.ApplicationAdapter.extend({
   pathForType: function() {
     return 'resources/file';
-  },
+  }
+});
+
+App.JobAdapter = App.ApplicationAdapter.extend({
+  deleteRecord: function (store, type, record)  {
+    var id = record.get('id');
+    return this.ajax(this.buildURL(type.typeKey, id)+ '?remove=true', "DELETE");
+  }
 });
 
 App.FileSerializer = DS.RESTSerializer.extend({
-  primaryKey:'filePath',
+  primaryKey:'filePath'
 });
 
 App.IsodateTransform = DS.Transform.extend({  
@@ -50,114 +57,114 @@ App.IsodateTransform = DS.Transform.extend({
   }
 });
 
+App.FileSaver = Ember.Object.extend({
+  save: function(fileContents, mimeType, filename) {
+    window.saveAs(new Blob([fileContents], {type: mimeType}), filename);
+  }
+});
+
+App.register('lib:fileSaver', App.FileSaver);
+
+
+
 Ember.Handlebars.registerBoundHelper('showDate', function(date,format) {
   return moment(date).format(format)
 });
 
 Em.TextField.reopen(Em.I18n.TranslateableAttributes)
 
-//////////////////////////////////
-// Templates
-//////////////////////////////////
-
 require('translations');
+require('router');
 
-require('templates/application');
-require('templates/index');
-require('templates/pig/loading');
-
-require('templates/pig');
-require('templates/pig/index');
-require('templates/pig/scriptList');
-require('templates/pig/scriptEdit');
-require('templates/pig/scriptEditIndex');
-require('templates/pig/scriptResults');
-require('templates/pig/scriptResultsNav');
-require('templates/pig/job');
-require('templates/pig/jobEdit');
-require('templates/pig/jobStatus');
-require('templates/pig/jobResults');
-require('templates/pig/jobResultsOutput');
-require('templates/pig/history');
-require('templates/pig/udfs');
-require('templates/pig/errorLog');
-
-require('templates/pig/util/script-nav');
-require('templates/pig/util/alert');
-require('templates/pig/util/alert-content');
-require('templates/pig/util/pigHelper');
-require('templates/pig/modal/confirmdelete');
-require('templates/pig/modal/createUdf');
-require('templates/pig/modal/modalLayout');
-require('templates/pig/modal/createScript');
-
-require('templates/splash');
-
-//////////////////////////////////
-// Models
-//////////////////////////////////
-
-require('models/pig_script');
-require('models/pig_job');
-require('models/file');
-require('models/udf');
-
-/////////////////////////////////
-// Controllers
-/////////////////////////////////
-
-require('controllers/pig');
-require('controllers/poll');
-require('controllers/edit');
-require('controllers/pigScriptEdit');
-require('controllers/pigScriptList');
-require('controllers/pigScriptEditResults');
-require('controllers/pigUdfs');
-require('controllers/pigHistory');
-require('controllers/pigJob');
-require('controllers/jobResults');
-require('controllers/splash');
-require('controllers/errorLog');
-require('controllers/util/pigUtilAlert');
-require('controllers/modal/pigModal');
-
-/////////////////////////////////
-// Views
-/////////////////////////////////
-
-require('views/pig');
-require('views/pig/scriptList');
-require('views/pig/scriptEdit');
-require('views/pig/scriptResults');
-require('views/pig/scriptResultsNav');
-require('views/pig/pigHistory');
-require('views/pig/pigUdfs');
-require('views/pig/pigJob');
-require('views/pig/jobResults');
-require('views/pig/modal/pigModal');
-require('views/pig/modal/confirmDelete');
-require('views/pig/modal/createUdf');
-require('views/pig/modal/createScript');
-require('views/pig/util/pigUtilAlert');
-
-/////////////////////////////////
-// Routes
-/////////////////////////////////
-
-require('routes/pig');
-require('routes/pigHistory');
-require('routes/pigIndex');
-require('routes/pigScriptEdit');
-require('routes/pigScriptEditIndex');
-require('routes/pigScriptEditResults');
-require('routes/pigScriptList');
-require('routes/pigUdfs');
-require('routes/pigJob');
-require('routes/jobResults');
-require('routes/splash');
-
-/////////////////////////////////
-// Router
-/////////////////////////////////
 
-require('router');
+// mixins
+require("mixins/fileHandler");
+require("mixins/pagination");
+
+//routes
+require("routes/pig");
+require("routes/pigHistory");
+require("routes/pigScripts");
+require("routes/pigUdfs");
+require("routes/script");
+require("routes/scriptEdit");
+require("routes/scriptHistory");
+require("routes/scriptJob");
+require("routes/splash");
+
+//models
+require("models/file");
+require("models/pig_job");
+require("models/pig_script");
+require("models/udf");
+
+//views
+require("views/pig");
+require("views/pig/alert");
+require("views/pig/history");
+require("views/pig/loading");
+require("views/pig/scripts");
+require("views/pig/udfs");
+require("views/script/edit");
+require("views/script/job");
+
+//controllers
+require("controllers/errorLog");
+require("controllers/modal/confirmAway");
+require("controllers/modal/confirmDelete");
+require("controllers/modal/deleteJob");
+require("controllers/modal/createScript");
+require("controllers/modal/createUdf");
+require("controllers/modal/gotoCopy");
+require("controllers/modal/logDownload");
+require("controllers/modal/pigModal");
+require("controllers/modal/resultsDownload");
+require("controllers/page");
+require("controllers/pig");
+require("controllers/pigAlert");
+require("controllers/pigHistory");
+require("controllers/pigScripts");
+require("controllers/pigUdfs");
+require("controllers/script");
+require("controllers/scriptEdit");
+require("controllers/scriptHistory");
+require("controllers/scriptJob");
+require("controllers/splash");
+
+//templates
+require("templates/application");
+require("templates/components/pigHelper");
+require("templates/components/scriptListRow");
+require("templates/loading");
+require("templates/modal/confirmAway");
+require("templates/modal/confirmDelete");
+require("templates/modal/createScript");
+require("templates/modal/deleteJob");
+require("templates/modal/createUdf");
+require("templates/modal/gotoCopy");
+require("templates/modal/logDownload");
+require("templates/modal/modalLayout");
+require("templates/modal/resultsDownload");
+require("templates/partials/alert-content");
+require("templates/partials/paginationControls");
+require("templates/pig");
+require("templates/pig/alert");
+require("templates/pig/errorLog");
+require("templates/pig/history");
+require("templates/pig/loading");
+require("templates/pig/scripts");
+require("templates/pig/udfs");
+require("templates/script");
+require("templates/script/edit");
+require("templates/script/history");
+require("templates/script/job");
+require("templates/splash");
+require('templates/error');
+
+//components
+require("components/codeMirror");
+require("components/helpers-data");
+require("components/jobProgress");
+require("components/pigHelper");
+require("components/scriptListRow");
+require("components/tabControl");

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/fileHandler.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/fileHandler.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/fileHandler.js
new file mode 100644
index 0000000..0c2c93c
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/fileHandler.js
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+var _promise = function (controller, url, output) {
+  return new Ember.RSVP.Promise(function(resolve,reject){
+    return Em.$.getJSON(url).then(function (data) {
+      resolve(data.file);
+    },function (error) {
+      var response = (error.responseJSON)?error.responseJSON:{};
+      reject(response.message);
+      if (error.status != 404) {
+        controller.send('showAlert', {'message': Em.I18n.t('job.alert.promise_error',
+          {status:response.status, message:response.message}), status:'error', trace: response.trace});
+      }
+    })
+  });
+};
+
+App.FileHandler = Ember.Mixin.create({
+  fileProxy:function (url) {
+    var promise,
+        host = this.store.adapterFor('application').get('host');
+        namespace = this.store.adapterFor('application').get('namespace');
+
+    url = [host, namespace, url].join('/');
+    promise = _promise(this, url,'stdout');
+
+    return Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
+      promise: promise
+    });
+  },
+  downloadFile:function (file,saveAs) {
+    return this.fileSaver.save(file, "application/json", saveAs);
+  }
+});
+
+App.inject('controller', 'fileSaver', 'lib:fileSaver');

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/pagination.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/pagination.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/pagination.js
new file mode 100644
index 0000000..587ede9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/mixins/pagination.js
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.Pagination = Ember.Mixin.create({
+  actions:{
+    selectPage: function(number) {
+      this.set('page', number);
+    },
+
+    toggleOrder: function() {
+      this.toggleProperty('sortAscending');
+    }
+  },
+
+  page: 1,
+
+  perPage: 10,
+
+  perPageOptions:[10,25,50,100],
+
+  pageWatcher:function () {
+    if (this.get('page') > this.get('totalPages')) {
+      this.set('page',this.get('totalPages') || 1);
+    };
+  }.observes('totalPages'),
+
+  totalPages: function() {
+    return Math.ceil(this.get('length') / this.get('perPage'));
+  }.property('length', 'perPage'),
+
+  pages: function() {
+    var collection = Ember.A();
+
+    for(var i = 0; i < this.get('totalPages'); i++) {
+      collection.pushObject(Ember.Object.create({
+        number: i + 1
+      }));
+    }
+
+    return collection;
+  }.property('totalPages'),
+
+  hasPages: function() {
+    return this.get('totalPages') > 1;
+  }.property('totalPages'),
+
+  prevPage: function() {
+    var page = this.get('page');
+    var totalPages = this.get('totalPages');
+
+    if(page > 1 && totalPages > 1) {
+      return page - 1;
+    } else {
+      return null;
+    }
+  }.property('page', 'totalPages'),
+
+  nextPage: function() {
+    var page = this.get('page');
+    var totalPages = this.get('totalPages');
+
+    if(page < totalPages && totalPages > 1) {
+      return page + 1;
+    } else {
+      return null;
+    }
+  }.property('page', 'totalPages'),
+
+
+  paginatedContent: function() {
+    var start = (this.get('page') - 1) * this.get('perPage');
+    var end = start + this.get('perPage');
+
+    return this.get('arrangedContent').slice(start, end);
+  }.property('page', 'totalPages', 'arrangedContent.[]'),
+
+  paginationInfo: function () {
+    var start = (this.get('page') - 1) * this.get('perPage') + 1;
+    var end = start + this.get('paginatedContent.length') - 1;
+    return start + ' - ' + end + ' of ' + this.get('arrangedContent.length')
+  }.property('page', 'arrangedContent.length', 'perPage')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
index e4217ae..b20a0ac 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
@@ -26,6 +26,10 @@ App.Job = DS.Model.extend({
   templetonArguments:DS.attr('string'),
   owner: DS.attr('string'),
   forcedContent:DS.attr('string'),
+  duration: DS.attr('number'),
+  durationTime:function () {
+    return moment.duration(this.get('duration'), "seconds").format("h [hrs], m [min], s [sec]");
+  }.property('duration'),
 
   sourceFile:DS.attr('string'),
   sourceFileContent:DS.attr('string'),
@@ -39,7 +43,7 @@ App.Job = DS.Model.extend({
   percentStatus:function () {
     if (this.get('isTerminated')) {
       return 100;
-    };
+    }
     return (this.get('status')==='COMPLETED')?100:(this.get('percentComplete')||0);
   }.property('status','percentComplete'),
 
@@ -86,5 +90,28 @@ App.Job = DS.Model.extend({
   },
   needsPing:function () {
     return this.pingStatusMap[this.get('status')];
-  }.property('status')
+  }.property('status'),
+
+  jobSuccess:function () {
+    return this.get('status') == 'COMPLETED';
+  }.property('status'),
+
+  jobError:function () {
+    return this.get('status') == 'SUBMIT_FAILED' || this.get('status') == 'KILLED' || this.get('status') == 'FAILED';
+  }.property('status'),
+
+  jobInProgress:function () {
+    return this.get('status') == 'SUBMITTING' || this.get('status') == 'SUBMITTED' || this.get('status') == 'RUNNING';
+  }.property('status'),
+
+  argumentsArray:function (q,w) {
+    if (arguments.length >1) {
+      var oldargs = (this.get('templetonArguments'))?this.get('templetonArguments').w():[];
+      if (w.length != oldargs.length) {
+        this.set('templetonArguments',w.join('\t'));
+      }
+    }
+    var args = this.get('templetonArguments');
+    return (args && args.length > 0)?args.w():[];
+  }.property('templetonArguments')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
index 74b0d6e..ab06c21 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
@@ -18,18 +18,8 @@
 
 var App = require('app');
 
-App.OpenedScript = Ember.Mixin.create({
-  opened:DS.attr('boolean'),
-  open:function (argument) {
-    return this.set('opened',true);
-  },
-  close:function (argument) {
-    return this.set('opened',false);
-  }
-});
-
-App.Script = DS.Model.extend(App.OpenedScript,{
-  title:DS.attr('string', { defaultValue: 'New script'}),
+App.Script = DS.Model.extend({
+  title:DS.attr('string'),
   pigScript:DS.belongsTo('file', { async: true }),
   dateCreated:DS.attr('isodate', { defaultValue: moment()}),
   templetonArguments:DS.attr('string', { defaultValue: '-useHCatalog'}),
@@ -40,4 +30,19 @@ App.Script = DS.Model.extend(App.OpenedScript,{
   label:function (){
     return this.get('title');
   }.property('title'),
+
+  argumentsArray:function (q,w) {
+    if (arguments.length >1) {
+      var oldargs = (this.get('templetonArguments'))?this.get('templetonArguments').w():[];
+      if (w.length != oldargs.length) {
+        this.set('templetonArguments',w.join('\t'));
+      }
+    }
+    var args = this.get('templetonArguments');
+    return (args && args.length > 0)?args.w():[];
+  }.property('templetonArguments'),
+
+  dateCreatedUnix:function () {
+    return moment(this.get('dateCreated')).unix();
+  }.property('dateCreated')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
index 66f2b6d..34c3be4 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
@@ -20,10 +20,11 @@ var App = require('app');
 
 App.Router.map(function () {
   this.resource('pig', { path: "/" }, function() {
-    this.route('scriptList',{ path: "/list" });
-    this.route('scriptEdit',{ path: "/edit/:script_id" });
-    this.resource('job', { path: "/job/:job_id" },function (argument) {
-      this.route('results');
+    this.route('scripts', { path: "/list" });
+    this.resource('script', { path: "/script" }, function () {
+      this.route('edit', { path: "/edit/:script_id" });
+      this.route('history', { path: "/history/:script_id" });
+      this.route('job', { path: "/job/:job_id" });
     });
     this.route('udfs');
     this.route('history');
@@ -31,7 +32,3 @@ App.Router.map(function () {
   });
   this.route('splash');
 });
-
-App.LoadingView = Em.View.extend({
-    templateName: 'pig/loading'
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js
deleted file mode 100644
index d01c69a..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.JobResultsRoute = Em.Route.extend({
-  enter: function() {
-      this.controllerFor('pig').set('category',"");
-      this.controllerFor('job').set('category',"results");
-    },
-  model: function (controller) {
-    return this.modelFor('job');
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
index e2eecd5..48fab5a 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
@@ -23,7 +23,7 @@ App.PigRoute = Em.Route.extend({
     App.set('previousTransition', transition);
   },
   redirect: function () {
-    testsConducted = App.get("smokeTests");
+    var testsConducted = App.get("smokeTests");
     if (!testsConducted) {
         App.set("smokeTests", true);
         this.transitionTo('splash');
@@ -34,38 +34,19 @@ App.PigRoute = Em.Route.extend({
       var location = (nav.hasOwnProperty('url'))?[nav.url]:['pig.scriptEdit',nav.get('id')];
       this.transitionTo.apply(this,location);
     },
-    close:function (script) {
-      var self = this;
-      script.close().save().then(function() {
-        if (self.get('controller.category') == script.get('name')) {
-          opened = self.get('controller.openScripts');
-          if (opened.length > 0 && opened.filterBy('id',script.get('id')).length == 0){
-            self.transitionTo('pig.scriptEdit',opened.get(0));
-          } else {
-            self.transitionTo('pig.scriptList');
-          }
-        }
-        self.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_saved',{title: script.get('title')}), status:'success'});
-      },function (error) {
-        //script.open();
-        var trace = null;
-        if (error && error.responseJSON.trace)
-          trace = error.responseJSON.trace;
-        self.send('showAlert', {'message': Em.I18n.t('scripts.alert.save_error_reason',{message:error.statusText}) , status:'error', trace:trace});
-      });
-    },
     showAlert:function (alert) {
-      var pigUtilAlert = this.controllerFor('pigUtilAlert');
-      return pigUtilAlert.content.pushObject(Em.Object.create(alert));
+      var pigAlert = this.controllerFor('pigAlert');
+      return pigAlert.content.pushObject(Em.Object.create(alert));
     },
-    openModal: function(modalName,controller) {
-      return this.render(modalName, {
+    openModal: function(modal,content) {
+      this.controllerFor(modal).set('content', content);
+      return this.render(['modal',modal].join('/'), {
         into: 'pig',
         outlet: 'modal',
-        controller:'pigModal'
+        controller:modal
       });
     },
-    closeModal: function() {
+    removeModal: function() {
       return this.disconnectOutlet({
         outlet: 'modal',
         parentView: 'pig'
@@ -77,6 +58,24 @@ App.PigRoute = Em.Route.extend({
   },
   renderTemplate: function() {
     this.render('pig');
-    this.render('pig/util/alert', {into:'pig',outlet:'alert',controller: 'pigUtilAlert' });
+    this.render('pig/alert', {into:'pig',outlet:'alert',controller:'pigAlert'});
+  }
+});
+
+App.PigIndexRoute = Em.Route.extend({
+  redirect:function () {
+    this.transitionTo('pig.scripts');
+  }
+});
+
+App.ErrorRoute = Ember.Route.extend({
+  setupController:function (controller,error) {
+    var data;
+    if(!(error instanceof Error)) {
+      data = JSON.parse(error.responseText);
+    } else {
+      data = error;
+    }
+    controller.set('model',data);
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
index cf9e3d5..9efa1c5 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
@@ -19,10 +19,24 @@
 var App = require('app');
 
 App.PigHistoryRoute = Em.Route.extend({
+  actions:{
+    error:function (error) {
+      this.controllerFor('pig').set('category',"");
+      var trace = (error.responseJSON)?error.responseJSON.trace:null;
+      this.send('showAlert', {message:Em.I18n.t('history.load_error'),status:'error',trace:trace});
+    }
+  },
   enter: function() {
     this.controllerFor('pig').set('category',"history");
   },
   model: function() {
     return this.store.find('job');
+  },
+  setupController:function (controller,model) {
+    var scripts = this.modelFor('pig');
+    var filtered = model.filter(function(job) {
+      return job.get('status') != 'SUBMIT_FAILED' && scripts.get('content').isAny('id',job.get('scriptId').toString());
+    });
+    controller.set('model',model);
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js
deleted file mode 100644
index 04e04dd..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigIndexRoute = Em.Route.extend({
-  beforeModel: function() {
-    this.transitionTo('pig.scriptList');
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js
deleted file mode 100644
index ca9b715..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.JobRoute = Em.Route.extend({
-    actions: {
-      error: function(error, transition) {
-        Em.warn(error.stack);
-        var trace = null;
-        if (error && error.responseJSON.trace)
-          trace = error.responseJSON.trace;
-        transition.send('showAlert', {'message':Em.I18n.t('job.alert.load_error',{message:error.message}), status:'error', trace:trace});
-        this.transitionTo('pig.scriptList');
-      },
-      navigate:function (argument) {
-        return this.transitionTo(argument.route)
-      }
-    },
-    setupController: function(controller, model) {
-      controller.set('model', model);
-      this.controllerFor('poll').set('model', model);
-    },
-    afterModel:function (job,arg) {
-      this.controllerFor('poll').get('pollster').start(job);
-    },
-    deactivate: function() {
-      this.controllerFor('poll').get('pollster').stop();
-    },
-    renderTemplate: function() {
-      this.render('pig/scriptEdit', {controller: 'job' });
-      this.render('pig/job', {into:'pig/scriptEdit',outlet: 'main', controller: 'poll' });
-      this.render('pig/scriptResultsNav',{into:'pig/scriptEdit',outlet: 'nav'});
-    }
-});
-
-App.JobIndexRoute = Em.Route.extend({
-  enter: function() {
-      this.controllerFor('pig').set('category',"");
-      this.controllerFor('job').set('category',"edit");
-    },
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js
deleted file mode 100644
index 2c19077..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptEditRoute = Em.Route.extend({
-  actions:{
-    willTransition: function(transition){
-      var model = this.controller.get('model');
-      if (model.get('isDirty') || model.get('pigScript.isDirty')) {
-        return this.send('saveScript',model);
-      };
-    },
-    toresults:function (argument) {
-      // DUMMY TRANSITION
-      this.transitionTo('pigScriptEdit.results',argument);
-    },
-    saveScript: function (script) {
-      var router = this,
-        onSuccess = function(model){
-          router.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_saved',{title: script.get('title')}),status:'success'});
-        },
-        onFail = function(error){
-          var trace = null;
-          if (error && error.responseJSON.trace)
-            trace = error.responseJSON.trace;
-          router.send('showAlert', {'message':Em.I18n.t('scripts.alert.save_error'),status:'error',trace:trace});
-        };
-
-      return script.get('pigScript').then(function(file){
-        return Ember.RSVP.all([file.save(),script.save()]).then(onSuccess,onFail);
-      },onFail);
-    },
-  },
-  isExec:false,
-  model: function(params) {
-    var record;
-    var isExist = this.store.all('script').some(function(script) {
-      return script.get('id') === params.script_id;
-    });
-    if (isExist) { 
-      record = this.store.find('script',params.script_id);
-    } else {
-      record = this.store.createRecord('script');
-    }
-    return record;
-  },
-  afterModel:function  (model) {
-    if (model.get('length') == 0) {
-      this.transitionTo('pig');
-    }
-    this.controllerFor('pig').set('category', model.get('name'));
-    model.open();
-  },
-  renderTemplate: function() {
-    this.render('pig/scriptEdit');
-  }
-});
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js
deleted file mode 100644
index 638ebe8..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptEditIndexRoute = Em.Route.extend({
-  renderTemplate: function() {
-    this.render('pig/scriptEditIndex',{
-      outlet: 'main',
-    });
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js
deleted file mode 100644
index 1a77e71..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptEditResultsRoute = Em.Route.extend({
-  model: function(params) {
-    return this.store.find('job',params.job_id);
-  },
-  afterModel:function (model) {
-    //this.controllerFor('pigScriptEdit').set('activeJob',model);
-  },
-  renderTemplate: function() {
-    this.render('pig/scriptResultsNav',{
-      outlet: 'nav',
-    });
-    this.render('pig/scriptResults',{
-      outlet: 'main',
-    });
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js
deleted file mode 100644
index 28d9e67..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-App.PigScriptListRoute = Em.Route.extend({
-  actions:{
-    createScript:function () {
-      var newScript = this.store.createRecord('script');
-      this.controllerFor('pigModal').set('content', newScript);
-      return this.send('openModal','createScript');
-      
-    },
-    deletescript:function (script) {
-      this.controllerFor('pigModal').set('content', script);
-      return this.send('openModal','confirmDelete');
-    },
-    confirmcreate:function (script,filePath) {
-      // /tmp/.pigscripts/admin/39.pig
-      var route = this;
-      var sendAlert = function (status) {
-        var alerts = {
-          success:Em.I18n.t('scripts.alert.script_created',{title:'New script'}), 
-          error: Em.I18n.t('scripts.alert.create_failed')
-        };
-        return function (data) {
-          var trace = null;
-          if (status=='error'){
-            script.deleteRecord();
-            trace = data.responseJSON.trace;
-          }
-          route.send('showAlert', {message:alerts[status],status:status,trace:trace});
-        };
-      };
-      if (filePath) {
-        var file = this.store.createRecord('file',{
-          id:filePath,
-          fileContent:''
-        });
-        return file.save().then(function(file){
-          script.set('pigScript',file);
-          script.save().then(sendAlert('success'),sendAlert('error'));
-        },function () {
-          file.deleteRecord();
-          route.store.find('file', filePath).then(function(file) {
-            route.send('showAlert', {message:Em.I18n.t('scripts.alert.file_exist_error'),status:'success'});
-            script.set('pigScript',file);
-            script.save().then(sendAlert('success'),sendAlert('error'));
-          }, sendAlert('error'));
-        });
-      } else {
-          script.save().then(sendAlert('success'),sendAlert('error'));
-      }
-
-
-    },
-    confirmdelete:function (script) {
-      var router = this;
-      var onSuccess = function(model){
-            router.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_deleted',{title : model.get('title')}),status:'success'});
-          };
-      var onFail = function(error){
-            var trace = null;
-            if (error && error.responseJSON.trace)
-              trace = error.responseJSON.trace;
-            router.send('showAlert', {'message':Em.I18n.t('scripts.alert.delete_failed'),status:'error',trace:trace});
-          };
-      script.deleteRecord();
-      return script.save().then(onSuccess,onFail);
-    }
-  },
-  enter: function() {
-    this.controllerFor('pig').set('category',"scripts");
-  },
-  model: function(object,transition) {
-    return this.modelFor('pig');
-  }
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScripts.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScripts.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScripts.js
new file mode 100644
index 0000000..edf3676
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScripts.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptsRoute = Em.Route.extend({
+  enter: function() {
+    this.controllerFor('pig').set('category','scripts');
+  },
+  model: function(object,transition) {
+    return this.modelFor('pig');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
index 7424bea..d6077ec 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
@@ -19,39 +19,6 @@
 var App = require('app');
 
 App.PigUdfsRoute = Em.Route.extend({
-  actions:{
-    createUdfModal:function () {
-      this.controllerFor('pigModal').set('content', this.store.createRecord('udf'));
-      return this.send('openModal','createUdf');
-    },
-    createUdf:function (udf) {
-      var router = this;
-      var onSuccess = function(model){
-          router.send('showAlert', {'message': Em.I18n.t('udfs.alert.udf_created',{name : model.get('name')}), status:'success'});
-        };
-      var onFail = function(error){
-          var trace = null;
-          if (error && error.responseJSON.trace)
-            trace = error.responseJSON.trace;
-          router.send('showAlert', {'message':Em.I18n.t('udfs.alert.create_failed'),status:'error',trace:trace});
-        };
-      return udf.save().then(onSuccess,onFail);
-    },
-    deleteUdf:function(udf){
-      var router = this;
-      var onSuccess = function(model){
-            router.send('showAlert', {'message': Em.I18n.t('udfs.alert.udf_deleted',{name : model.get('name')}),status:'success'});
-          };
-      var onFail = function(error){
-            var trace = null;
-            if (error && error.responseJSON.trace)
-              trace = error.responseJSON.trace;
-            router.send('showAlert', {'message': Em.I18n.t('udfs.alert.delete_failed'),status:'error',trace:trace});
-          };
-      udf.deleteRecord();
-      return udf.save().then(onSuccess,onFail);
-    }
-  },
   enter: function() {
     this.controllerFor('pig').set('category',"udfs");
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/script.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/script.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/script.js
new file mode 100644
index 0000000..f3e7fcd
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/script.js
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptRoute = Em.Route.extend({
+  actions:{
+    willTransition:function (transition) {
+      if (this.controllerFor('script.edit').get('isExec')) {
+        return transition.abort();
+      }
+      if (this.controllerFor('script.edit').get('isRenaming')) {
+        this.controllerFor('script.edit').set('titleWarn',true);
+        return transition.abort();
+      }
+      var isAway = this.isGoingAway(transition);
+      var scriptDirty = this.controllerFor('pig').get('scriptDirty');
+      if (isAway && scriptDirty) {
+        transition.abort();
+        this.send('openModal','confirmAway',transition);
+      }
+    }
+  },
+  enter:function () {
+    this.controllerFor('pig').set('category', '');
+  },
+  deactivate: function() {
+    this.controllerFor('pig').set('activeScriptId', null);
+    this.controllerFor('script').set('activeJobs',[]);
+  },
+  isGoingAway:function (transition) {
+    var isScriptAway = !transition.targetName.match(/^script./);
+    if (!isScriptAway) {
+      var targetParams = transition.params[transition.targetName];
+      if (targetParams['script_id']) {
+        return targetParams['script_id'] != this.controllerFor('pig').get('activeScriptId');
+      };
+      if (targetParams['job_id'] && this.modelFor('script.history')) {
+        return this.modelFor('script.history').get('content').filterBy('id',targetParams['job_id']).length == 0;
+      };
+    };
+    return isScriptAway;
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptEdit.js
new file mode 100644
index 0000000..04b430d
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptEdit.js
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptEditRoute = Em.Route.extend({
+  enter:function () {
+    this.controllerFor('script').set('activeTab','script');
+  },
+  isExec:false,
+  model: function(params) {
+    var record;
+    var isExist = this.store.all('script').some(function(script) {
+      return script.get('id') === params.script_id;
+    });
+    if (isExist) {
+      record = this.store.find('script',params.script_id);
+    } else {
+      record = this.store.createRecord('script');
+    }
+    return record;
+  },
+  afterModel:function  (model) {
+    if (model.get('length') == 0) {
+      this.transitionTo('pig');
+    }
+    this.controllerFor('pig').set('activeScriptId', model.get('id'));
+  },
+  renderTemplate: function() {
+    this.render('script/edit');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptHistory.js
new file mode 100644
index 0000000..650bfb9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptHistory.js
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptHistoryRoute = Em.Route.extend({
+  enter: function() {
+    this.controllerFor('script').set('activeTab','history');
+  },
+  model:function(param) {
+    this.controllerFor('pig').set('activeScriptId', param.script_id);
+    return this.store.find('job', {scriptId: param.script_id});
+  },
+  setupController:function (controller,model) {
+    var script_id = this.controllerFor('pig').get('activeScriptId');
+    model.store.recordArrayManager.registerFilteredRecordArray(model,model.type,function(job) {
+      return job.get('scriptId') == script_id;
+    });
+    controller.set('model',model);
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptJob.js
new file mode 100644
index 0000000..28ce908
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/scriptJob.js
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ScriptJobRoute = Em.Route.extend({
+    actions: {
+      error: function(error, transition) {
+        Em.warn(error.stack);
+        var trace = null;
+        if (error && error.responseJSON.trace)
+          trace = error.responseJSON.trace;
+        transition.send('showAlert', {'message':Em.I18n.t('job.alert.load_error',{message:error.message}), status:'error', trace:trace});
+        this.transitionTo('pig.scripts');
+      },
+      navigate:function (argument) {
+        return this.transitionTo(argument.route)
+      },
+      killjob:function (job) {
+        var self = this;
+        job.kill(function () {
+          job.reload();
+          self.send('showAlert', {'message': Em.I18n.t('job.alert.job_killed',{title:self.get('title')}), status:'info'});
+        },function (reason) {
+          var trace = null;
+          if (reason && reason.responseJSON.trace)
+            trace = reason.responseJSON.trace;
+          self.send('showAlert', {'message': Em.I18n.t('job.alert.job_kill_error'), status:'error', trace:trace});
+        });
+      }
+    },
+    model:function (q,w) {
+      return this.store.find('job',q.job_id);
+    },
+    setupController: function(controller, model) {
+      controller.set('model', model);
+    },
+    afterModel:function (job) {
+      this.controllerFor('pig').set('activeScriptId', job.get('scriptId'));
+      this.controllerFor('script').get('activeJobs').addObject(job);
+      this.controllerFor('script').set('activeTab',job.get('id'));
+    }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/splash.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/splash.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/splash.js
index ef7aa4d..5223a5a 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/splash.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/splash.js
@@ -20,13 +20,15 @@ var App = require('app');
 
 App.SplashRoute = Em.Route.extend({
   model: function() {
-    return Ember.Object.create({storageTest: null,
-                                storageTestDone: null,
-                                webhcatTest: null,
-                                webhcatTestDone: null,
-                                hdfsTest: null,
-                                hdfsTestDone: null,
-                                percent: 0});
+    return Ember.Object.create({
+      storageTest: null,
+      storageTestDone: null,
+      webhcatTest: null,
+      webhcatTestDone: null,
+      hdfsTest: null,
+      hdfsTestDone: null,
+      percent: 0
+    });
   },
   renderTemplate: function() {
     this.render('splash');
@@ -41,7 +43,7 @@ App.SplashRoute = Em.Route.extend({
           if (previousTransition) {
             previousTransition.retry();
           } else {
-            self.transitionTo('pig.scriptList');
+            self.transitionTo('pig.scripts');
           }
         }, 1000);
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less b/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
index 75df9c0..c8b8576 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
@@ -16,9 +16,17 @@
  * limitations under the License.
  */
 
+@import './../../bower_components/bootstrap/less/variables.less';
+
+@screen-md:                  900px;
+@modal-backdrop-opacity:      0;
+
+@import './../../bower_components/bootstrap/less/bootstrap.less';
+
 .wrap {
-	padding: 15px;
+  padding: 15px;
 }
+
 .moz-padding (@selector, @pre: ~'', @padding) {
   @-moz-document url-prefix() {
     @{pre}@{selector} {
@@ -51,9 +59,128 @@
 
 // navigation
 .navigation {
-  //position: fixed;
-  a {
-    cursor: pointer;
+  .well {
+    padding: 0;
+    background-color: #f5f5f5;
+    height: 200px;
+    overflow: hidden;
+    .nav-main {
+      &.collapsed {
+        a {
+          border-right: 1px solid transparent;
+        }
+      }
+      float: left;
+      width: 100%;
+      text-align:  center;
+      &.list-group-item:first-child{
+        border-top-left-radius: 4px;
+      }
+      a {
+        &.list-group-item:hover,
+        &.list-group-item:focus {
+          background-color: lighten(#f5f5f5, 3%);
+          border-color: #e9e9e9;
+        }
+        &.list-group-item.active,
+        &.list-group-item.active:hover,
+        &.list-group-item.active:focus {
+          z-index: 60;
+          color: black;
+          background-color: lighten(#f5f5f5, 3%);
+          border-color: #dadada;
+          .common-shadow-inset;
+        }
+        &.list-group-item:first-child{
+          border-radius: 0;
+          border-top: 0;
+        }
+        &.list-group-item:last-child {
+          border-radius: 0;
+        }
+        span {
+          bottom: 4px;
+          position: relative;
+          margin-left: 15px;
+        }
+        cursor: pointer;
+        background-color: transparent;
+        border-top: 1px solid transparent;
+        border-bottom: 1px solid transparent;
+        border-right: 0;
+        border-left:0;
+
+        .base-transition( background-color 200ms linear;);
+      }
+    }
+    .nav-script-wrap {
+      &.in {
+        &.reveal {
+          left: 125px;
+        }
+        left: 65px;
+      }
+      z-index: 70;
+      width: 100%;
+      left: 102%;
+      position: relative;
+      height: 100%;
+      box-shadow: -2px 0px 1px rgba(0, 0, 0, 0.20);
+      .base-transition( left 300ms linear;);
+
+      .nav-script {
+        position: absolute;
+        width: 100%;
+        background-color: @gray-dark;
+        height: 100%;
+
+        & div:first-child {
+          margin-bottom: 25px;
+          button {
+            position: relative;
+            float: right;
+            right: 65px;
+            color: @gray-light;
+            border: 0;
+            background-color: transparent;
+            margin: 1px;
+            &:hover {
+              color: @gray-lighter;
+            }
+          }
+        }
+
+        .script-title {
+          background: #fff;
+          padding: 8px;
+          //border: 1px solid #747474;
+          margin-bottom: 10px;
+        }
+       .script-actions {
+          padding-left: 10px;
+          padding-right: 10px;
+          li {
+              margin: 9px 0;
+            &.divider {
+              height: 1px;
+              margin: 9px 0;
+              overflow: hidden;
+              background-color: #e5e5e5;
+            }
+            a {
+              color: #fff;
+              text-align: left;
+              padding: 0;
+              &:hover {
+                color: darken(#fff, 30%);
+                text-decoration: none;
+              }
+            }
+          }
+       }
+
+      }
+    }
   }
   .pig-nav-item {
     word-break: break-word;
@@ -66,25 +193,101 @@
   }
 }
 
+.nav-tabs-script {
+  margin-bottom: 10px;
+  .job > a {
+    padding: 10px 25px 10px 15px;
+  }
+  .active > .btn {
+    color: #111;
+  }
+  .btn {
+    &:hover {
+      color: @brand-danger;
+    }
+    position: absolute;
+    color: @brand-primary;
+    top: 1px;
+    padding: 0px;
+    background: transparent;
+    right: 3px;
+    padding: 0px 4px;
+  }
+}
+
+.scriptlist, .panel-udfs, .panel-history {
+  .title-row {
+    height: 55px;
+  }
+}
+
 //script list
-.panel-scriptlist {
+.scriptlist {
   .new-script {
-    position: relative;
-    top:-5px;
+    margin-top: 15px;
+    /*position: relative;
+    top:-5px;*/
+  }
+  table {
+    th:last-child {
+      width: 260px;
+    }
+    td > h4 {
+      margin: 0;
+    }
+    td:last-child > a {
+      margin-right: 15px;
+    }
+  }
+}
+
+.pagination-block {
+  color: #7b7b7b;
+  & > div {
+    display: inline-block;
+    margin-left: 15px;
+  }
+  text-align: right;
+  .items-count {
+    vertical-align: top;
+    label {
+      font-weight: normal;
+    }
+    select {
+      display: inline-block;
+      width: auto;
+      padding: 0px 8px;
+      height: 28px;
+    }
+  }
+  .items-info {
+    vertical-align: top;
+    padding: 4px 0;
+  }
+  .items-buttons {
+    .pagination {
+      margin: 0;
+      & > li > a, & > li > span {
+        padding: 3px 12px;
+        border-color: transparent;
+        &:hover {
+          background-color: #fff;
+        }
+      }
+    }
   }
 }
 
 //udfs
 .panel-udfs {
   .upload-udf {
-    position: relative;
-    top:-5px;
+    margin-top: 15px;
   }
 }
 
 .argument-label {
   vertical-align: middle;
-  background-color: #999999;
+  background-color: @gray-light;
   display: inline-block;
   font-size: 75%;
   font-weight: bold;
@@ -103,6 +306,7 @@
 //edit script
 .edit-script {
   .panel-editscript {
+    margin-bottom: 5px;
     textarea {
       width: 100%;
       max-width: 100%;
@@ -116,7 +320,16 @@
     }
     .CodeMirror {
       .common-shadow-inset;
-
+      height:500px;
+      .CodeMirror-hscrollbar {
+        left: 0 !important;
+      }
+    }
+    #sgrip {
+      position: absolute;
+      left: 50%;
+      cursor: s-resize;
+      color: #999999;
     }
     .table-results {
       .argument {
@@ -128,19 +341,24 @@
       background-color: #f5f5f5;
     }
     .panel-heading{
-      .input-title {
-        width: 1%;
-        #title {
-          width: 250px;
-          display: inline-block;
+      .script-title {
+        display: inline-block;
+        h4 {
+          margin-bottom: 5px;
+          .btn-rename {
+            margin-left: 10px;
+          }
         }
+      }
 
-        .btn-rename-ask {
-          background-color: #f5f5f5;
+      .input-title {
+        width: 45%;
+        min-width: 200px;
+        .tooltip-arrow {
+          border-bottom-color: #a94442;
         }
-
-        .btn-rename-ask:hover {
-          background-color: #fff;
+        .tooltip-inner {
+          background-color: #a94442;
         }
 
         .btn-rename-cancel{
@@ -153,8 +371,8 @@
       }
     }
     .panel-body {
-      padding: 5px; 
-      background-color: #f5f5f5; 
+      padding: 5px;
+      background-color: #f5f5f5;
       border-bottom: 1px solid #dddddd;
       .argadd {
         font-size: 13px;
@@ -213,28 +431,173 @@
       }
     }
   }
-  .pigParams {
-    padding-bottom: 10px; 
+  .params-block {
+    .block-title {
+      border-bottom: 2px solid #dddddd;
+      margin-bottom: 10px;
+      padding: 5px 0;
+    }
+    .pigParams {
+      padding-bottom: 10px;
+    }
+  }
+  .arguments-block {
+    .block-title {
+      border-bottom: 2px solid #dddddd;
+      margin-bottom: 10px;
+      padding: 5px 0;
+    }
+    .alert {
+      padding: 6px 15px;
+      margin-bottom: 5px;
+    }
+    .arguments-wrap {
+      .label {
+        padding: 10px ;
+        display: inline-block;
+        font-size: 100%;
+        margin-bottom: 5px;
+        a {
+          margin-left: 5px;
+          font-size: 100%;
+        }
+      }
+    }
+  }
+}
+
+.script_history_container{
+  table {
+    th:last-child {
+      width: 250px;
+    }
+    td > h4 {
+      margin: 0;
+    }
+    td > a {
+      margin-right: 15px;
+    }
+  }
+}
+
+.panel-history {
+  table {
+    th:first-child {
+      width: 140px;
+    }
+    th:last-child {
+      width: 110px;
+    }
+    td > h4 {
+      margin: 0;
+    }
+    td > a {
+      margin-right: 15px;
+    }
+    .scriptLink {
+      &.inactive {
+        text-decoration: none;
+        background-color: transparent;
+        cursor: auto;
+        color: #999999;
+      }
+      cursor: pointer;
+    }
   }
 }
 
-.job-status-view {
-  .progress {
-    margin-bottom: 0;
+.job-container {
+  .progress-wrap {
+    .base-transition( width 200ms linear;);
+  }
+  .panel-title {
+    font-weight: normal;
+    a {
+      text-decoration: none;
+    }
+    .toggle-icon {
+      transition: all 0.3s;
+    }
+  }
+  #scriptResults .panel-body, #scriptLogs .panel-body {
+    max-height: 550px;
+    overflow-x: hidden;
+    background-color: #fcfcfc;
+    pre {
+      margin: 0;
+      padding: 0;
+      border: 0;
+      border-radius: 0;
+      background-color: #fcfcfc;
+    }
+  }
+  .CodeMirror {
+    .common-shadow-inset;
+    height: 215px;
+    border-bottom: 1px solid #dddddd;
+    .CodeMirror-gutters {
+      background-color: #fcfcfc;
+    }
+    .CodeMirror-hscrollbar {
+      left: 0 !important;
+    }
+  }
+  #sgrip {
+      position: absolute;
+      left: 50%;
+      cursor: s-resize;
+      color: #999999;
+    }
+
+  .arguments-wrap {
+    padding: 5px;
+    .label {
+      padding: 5px;
+      display: inline-block;
+      font-size: 100%;
+      margin-bottom: 5px;
+    }
+  }
+
+  #scriptDetails {
+    .body-title {
+      padding: 5px;
+      background-color: #fcfcfc;
+      border-bottom: 1px solid #dddddd;
+    }
+    .alert {
+      border: none;
+      border-radius: 0;
+      margin-bottom: 0;
+    }
   }
-  .kill-button {
-    float: left; 
-    margin-right: 10px;
+
+  .job-info {
+    td {
+     /* textarea {
+        width: 100%;
+        max-width: 100%;
+        height: 300px;
+      }*/
+      border: 0;
+      &:first-child {
+        width: 120px;
+      }
+    }
   }
+
 }
 
 //utils
 #alert-wrap {
-  position: fixed;
-  bottom: 0;
-  width: 16.666666666666664%;
-  padding-right: 30px;
+  //position: fixed;
+  //bottom: 0;
+  //width: 16.666666666666664%;
+  //padding-right: 30px;
   font-size: 0.9em;
+width: 100%;
+z-index: 3;
+opacity: 0.89;
   
   .alert {
     .common-shadow;
@@ -350,15 +713,6 @@
   border-radius:6px 0 6px 6px;
 }
 
-
-a.list-group-item.active{
-  z-index: 2;
-  color: #ffffff;
-  background-color: #428bca;
-  border-color: #428bca;
-  .base-transition(border-color 200ms linear, background-color 200ms linear;);
-}
-
 .empty-table-footer {
   text-align: center;
   font-size: 13pt;
@@ -373,6 +727,27 @@ a.list-group-item.active{
 .green {
     color: green;
 }
+
 .red {
     color: red;
-}
\ No newline at end of file
+}
+
+.resultsModal, .logModal {
+  .modal-header p {
+    width: 55%;
+  }
+  .modal-body {
+    height: 550px;
+    overflow-y: scroll;
+    background-color: #f5f5f5;
+    pre {
+      margin: 0;
+      padding: 0;
+      border: 0;
+      border-radius: 0;
+    }
+  }
+  .modal-footer {
+    margin-top: 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/pigHelper.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/pigHelper.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/pigHelper.hbs
new file mode 100644
index 0000000..4c1596d
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/pigHelper.hbs
@@ -0,0 +1,34 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
+  {{t 'editor.pighelper'}}
+  <span class="caret"></span>
+</button>
+<ul class="dropdown-menu" id="pig_helper">
+  {{#each view.helpers}}
+    <li class="dropdown-submenu">
+      <a>{{this.title}}</a>
+      <ul class="dropdown-menu">
+        {{#each this.helpers }}
+          <li><a href="#" {{action 'putToEditor' this target="view" }} >{{this}}</a></li>
+        {{/each}}
+      </ul>
+    </li>
+  {{/each}}
+</ul>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/scriptListRow.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/scriptListRow.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/scriptListRow.hbs
new file mode 100644
index 0000000..7f6532f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/components/scriptListRow.hbs
@@ -0,0 +1,44 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<td class="first">
+  {{#link-to 'script.edit' id}}
+    {{#if isNew}}
+      <div class="spinner-sm"></div>
+    {{/if}}
+    {{#unless isNew}}
+      {{title}}
+    {{/unless}}
+  {{/link-to}}
+</td>
+<td>
+  {{#if view.currentJob}}
+    <span class="date">{{showDate view.currentJob.dateStarted 'YYYY-MM-DD HH:mm'}}</span>
+  {{else}}
+    {{t 'scripts.not_run_message'}}
+  {{/if}}
+</td>
+<td>
+  {{view.currentJob.status}}
+</td>
+<td>
+  {{#unless isNew}}
+    {{#link-to 'script.history' id}}{{t 'common.history'}}{{/link-to}} -
+    <a href="#" {{action "deletescript" this}}>{{t 'common.delete'}}</a>
+  {{/unless}}
+</td>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/error.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/error.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/error.hbs
new file mode 100644
index 0000000..b3e6033
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/error.hbs
@@ -0,0 +1,35 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+<div class="panel panel-danger">
+  <div class="panel-heading">
+    <div class="text-center">
+      <strong>{{content.status}}</strong>  {{content.message}}
+      {{#if content.trace}}
+        <a data-toggle="collapse" class="btn btn-danger btn-xs" href="#collapseTrace">Trace <span class="caret"></span></a>
+      {{/if}}
+    </div>
+  </div>
+  <div id="collapseTrace" class="panel-collapse collapse">
+    <div class="panel-body">
+      <pre>
+        {{content.trace}}
+      </pre>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs
deleted file mode 100644
index 0efb5b2..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs
+++ /dev/null
@@ -1,18 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmAway.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmAway.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmAway.hbs
new file mode 100644
index 0000000..3c12506
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmAway.hbs
@@ -0,0 +1,32 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm' option="discard" }}
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h4 class="modal-title">{{t 'common.warning'}}</h4>
+  </div>
+  <div class="modal-body">
+    {{t 'scripts.modal.unsaved_changes_warning'}}
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
+    <button type="button" {{action "option" target="view" }} {{bind-attr class=":btn :btn-danger"}}>{{t 'common.discard_changes'}}</button>
+    <button type="button" {{action "ok" target="view"}} {{bind-attr class=":btn :btn-success"}}>{{t 'common.save'}}</button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmDelete.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmDelete.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmDelete.hbs
new file mode 100644
index 0000000..b71854f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/confirmDelete.hbs
@@ -0,0 +1,31 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm'}}
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h4 class="modal-title">{{t 'scripts.modal.confirm_delete'}}</h4>
+  </div>
+  <div class="modal-body">
+  {{t 'scripts.modal.confirm_delete_massage' titleBinding="content.title" tagName="p"}}
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'common.cancel'}}</button>
+    <button type="button" {{action "ok" content target="view"}} class="btn btn-danger">{{t 'common.delete'}}</button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createScript.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createScript.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createScript.hbs
new file mode 100644
index 0000000..cfe3f58
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createScript.hbs
@@ -0,0 +1,42 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm' close='cancel' escape-press='cancel'}}
+  <div class="modal-header">
+    <button type="button" class="close" {{action "cancel" target="view"}} aria-hidden="true">&times;</button>
+    <h4 class="modal-title">{{t 'scripts.modal.create_script'}}</h4>
+  </div>
+  <div class="modal-body">
+  <div class="form-group">
+      <label>{{t 'scripts.title'}}</label>
+      {{input class="form-control" placeholderTranslation="scripts.modal.script_title_placeholder" valueBinding="content.title"}}
+    </div>
+    {{#if titleError}}
+      <div class="alert alert-danger">{{titleError}}</div>
+    {{/if}}
+    <div class="form-group">
+      <label for="exampleInputPassword1">{{t 'scripts.path'}}</label>
+      {{input class="form-control" placeholderTranslation="scripts.modal.file_path_placeholder" valueBinding="filePath"}}
+      <small class="pull-right help-block">{{t 'scripts.modal.file_path_hint'}}</small>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
+    <button type="button" {{action "ok" target="view"}} {{bind-attr class="titleError:disabled :btn :btn-success"}} >{{t 'common.create'}}</button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createUdf.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createUdf.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createUdf.hbs
new file mode 100644
index 0000000..6f1ffb2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/createUdf.hbs
@@ -0,0 +1,38 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm' close='cancel'}}
+  <div class="modal-header">
+    <button type="button" class="close" {{action "cancel" target="view"}} aria-hidden="true">&times;</button>
+    <h4 class="modal-title">{{t 'udfs.modal.create_udf'}}</h4>
+  </div>
+  <div class="modal-body">
+  <div class="form-group">
+      <label for="exampleInputEmail1">{{t 'common.name'}}</label>
+      {{input class="form-control" placeholderTranslation="udfs.modal.udf_name" valueBinding="content.name"}}
+    </div>
+    <div class="form-group">
+      <label for="exampleInputPassword1">{{t 'common.path'}}</label>
+      {{input class="form-control" placeholderTranslation="udfs.modal.hdfs_path" valueBinding="content.path"}}
+    </div>
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" content target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
+    <button type="button" {{action "ok" target="view"}} {{bind-attr class=":btn :btn-success udfInvalid:disabled"}}>{{t 'common.create'}}</button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/deleteJob.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/deleteJob.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/deleteJob.hbs
new file mode 100644
index 0000000..0f4c74f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/deleteJob.hbs
@@ -0,0 +1,31 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm'}}
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h4 class="modal-title">{{t 'scripts.modal.confirm_delete'}}</h4>
+  </div>
+  <div class="modal-body">
+  {{t 'job.modal.confirm_delete_massage' titleBinding="content.title" tagName="p"}}
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'common.cancel'}}</button>
+    <button type="button" {{action "ok" content target="view"}} class="btn btn-danger">{{t 'common.delete'}}</button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/gotoCopy.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/gotoCopy.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/gotoCopy.hbs
new file mode 100644
index 0000000..1d4fcdb
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/gotoCopy.hbs
@@ -0,0 +1,31 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm'}}
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h4 class="modal-title">{{t 'scripts.modal.copy_created'}}</h4>
+  </div>
+  <div class="modal-body">
+    {{t 'scripts.modal.copy_created_massage' titleBinding="content.title" tagName="p"}}
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'scripts.modal.continue_editing'}}</button>
+    <button type="button" {{action "ok" content target="view"}} class="btn btn-primary">{{t 'scripts.modal.go_to_copy'}}</button>
+  </div>
+{{/pig-modal}}


[06/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/logDownload.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/logDownload.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/logDownload.hbs
new file mode 100644
index 0000000..ed47d62
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/logDownload.hbs
@@ -0,0 +1,42 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm' size='lg' class='logModal'}}
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    {{#if jobLogsLoader.isFulfilled}}
+    <p class="pull-right" ><a href="#" {{action 'download'}}><i class="fa fa-download"></i> {{t 'common.download'}}</a></p>
+    {{/if}}
+    <h4 class="modal-title">{{t 'job.logs'}} </h4>
+  </div>
+  <div class="modal-body">
+    {{#if jobLogsLoader.isPending}}
+      <pre><div class="spinner-sm"></div></pre>
+    {{else}}
+      {{#if jobLogsLoader.isFulfilled}}
+      <pre>{{jobLogsLoader.content.fileContent}}</pre>
+      {{/if}}
+      {{#if jobLogsLoader.isRejected}}
+        {{jobLogsLoader.reason}}
+      {{/if}}
+    {{/if}}
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'common.close'}} </button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/modalLayout.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/modalLayout.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/modalLayout.hbs
new file mode 100644
index 0000000..0aca82f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/modalLayout.hbs
@@ -0,0 +1,25 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="modal fade in" data-backdrop="static">
+  <div {{bind-attr class=":modal-dialog large:modal-lg small:modal-sm" }}>
+    <div class="modal-content">
+      {{yield}}
+    </div><!-- /.modal-content -->
+  </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/resultsDownload.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/resultsDownload.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/resultsDownload.hbs
new file mode 100644
index 0000000..5de0cfa
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/modal/resultsDownload.hbs
@@ -0,0 +1,42 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{#pig-modal ok='confirm' size='lg' class='resultsModal'}}
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+      {{#if jobResultsLoader.isFulfilled}}
+      <p class="pull-right" ><a href="#" {{action 'download'}}><i class="fa fa-download"></i> {{t 'common.download'}}</a></p>
+      {{/if}}
+    <h4 class="modal-title">{{t 'job.results'}}</h4>
+  </div>
+  <div class="modal-body">
+    {{#if jobResultsLoader.isPending}}
+      <pre><div class="spinner-sm"></div></pre>
+    {{else}}
+      {{#if jobResultsLoader.isFulfilled}}
+      <pre>{{jobResultsLoader.content.fileContent}}</pre>
+      {{/if}}
+      {{#if jobResultsLoader.isRejected}}
+        {{jobResultsLoader.reason}}
+      {{/if}}
+    {{/if}}
+  </div>
+  <div class="modal-footer">
+    <button type="button" {{action "cancel" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'common.close'}}</button>
+  </div>
+{{/pig-modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/alert-content.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/alert-content.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/alert-content.hbs
new file mode 100644
index 0000000..08ce680
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/alert-content.hbs
@@ -0,0 +1,25 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<button type="button" class="close" >&times;</button>
+<p>
+  {{view.content.message}}
+</p>
+{{#if view.content.trace}}
+    <a href="#" {{action 'showErrorLog' view.content}}>{{t 'common.showErrorLog'}}</a>
+{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/paginationControls.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/paginationControls.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/paginationControls.hbs
new file mode 100644
index 0000000..5543b94
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/partials/paginationControls.hbs
@@ -0,0 +1,42 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="pagination-block">
+  <div class="items-count">
+    <label >{{t 'common.show'}}
+      {{view Ember.Select content=perPageOptions class="form-control" value=perPage}}
+    </label>
+  </div>
+  <div class="items-info">
+    <span>{{paginationInfo}}</span>
+  </div>
+  <div class="items-buttons">
+    <ul class="pagination">
+      {{#if prevPage}}
+        <li><a href="#" {{action "selectPage" prevPage}}><i class="fa fa-arrow-left"></i></a></li>
+      {{else}}
+        <li class="disabled"><a><i class="fa fa-arrow-left"></i></a></li>
+      {{/if}}
+      {{#if nextPage}}
+        <li><a href="#" {{action "selectPage" nextPage}}><i class="fa fa-arrow-right"></i></a></li>
+      {{else}}
+        <li class="disabled"><a><i class="fa fa-arrow-right"></i></a></li>
+      {{/if}}
+    </ul>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
index 70e87ae..881fd82 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
@@ -18,11 +18,37 @@
 
 <div class="container-fluid">
   <div class="row">
-    <div class="col-md-2 navigation">
-      {{view view.navItemsView}}
+    <div class="col-md-3 navigation">
+      <div class="well">
+
+        {{view view.navItemsView}}
+        <div class="nav-script-wrap">
+          <div class=" nav-script" >
+            <div>
+              <button type="button" class="close_script" {{action closeScript}}>
+                <i class="fa fa-times"></i>
+              </button>
+            </div>
+            <div class="script-title">
+              {{#if activeScript.label}}
+                <span>{{activeScript.label}}</span>
+                {{else}}
+                <span>...</span>
+              {{/if}}
+            </div>
+           <ul class="script-actions list-unstyled">
+              <li><a href="#" {{action "saveScript" activeScript}} {{bind-attr class=":btn :btn-block saveEnabled::disabled"}} ><i class="fa fa-fw fa-save"></i> {{t 'common.save'}}</a></li>
+              <li><a href="#" {{action "copyScript" activeScript}} {{bind-attr class=":btn :btn-block disableScriptControls:disabled"}} ><i class="fa fa-fw fa-copy"></i> {{t 'common.copy'}}</a></li>
+              <li class="divider"></li>
+              <li><a href="#" {{action "deletescript" activeScript}} {{bind-attr class=":btn :btn-block disableScriptControls:disabled"}}  ><i class="fa fa-fw fa-trash-o"></i> {{t 'common.delete'}}</a></li>
+            </ul>
+          </div>
+        </div>
+      </div>
+
       {{outlet alert}}
     </div>
-    <div class="col-md-10">
+    <div class="col-md-9">
       {{outlet}}
     </div>
   </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/alert.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/alert.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/alert.hbs
new file mode 100644
index 0000000..c3a2215
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/alert.hbs
@@ -0,0 +1,21 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div id="alert-wrap">
+ {{view view.alertsView}}
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
index a5a4af9..e58e0df 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
@@ -16,37 +16,53 @@
    limitations under the License.
 }}
 
-<div class="panel panel-default panel-history">
-  <div class="panel-heading">
-    <span class="panel-title">
-      {{t 'common.history'}}
-    </span>
+<div class="panel-history">
+  <div class="title-row">
+    <h3 class="pull-left"> {{t 'common.history'}}</h3>
   </div>
-  
-  <table class="table table-bordered table-striped ">
+  <table class="table table-striped ">
     <thead> 
       <tr class="label-row">
-        <th class="first">{{t 'job.name'}}</th>
-        <th>{{t 'job.started'}}</th> 
+        <th>{{t 'common.date'}}</th>
+        <th>{{t 'scripts.script'}}</th>
         <th>{{t 'job.status'}}</th> 
-        <th></th> 
+        <th>{{t 'history.duration'}}</th>
+        <th>{{t 'common.actions'}}</th>
       </tr>
     </thead>
     <tbody> 
-    {{#each jobs}}
-      {{#view view.historyTableRow}}
-        <tr> 
-          <td class="first">{{#link-to 'job' this.id }} {{this.title}}{{/link-to}}</td>
-          <td><span class="date">{{showDate this.dateStarted 'YYYY-MM-DD HH:mm'}}</span></td>
-          <td><span {{bind-attr class=":label view.labelClass"}}>{{this.status}}</span></td>
-          <td>{{#link-to 'job.results' this.id }} {{t 'job.results'}} {{/link-to}}</td>
-        </tr>
-      {{/view}}
+    {{#each paginatedContent}}
+      <tr>
+        <td>{{#link-to 'script.job' this.id }} {{showDate this.dateStarted 'YYYY-MM-DD HH:mm'}} {{/link-to}}</td>
+        <td>
+          {{#view 'view.scriptLink' scriptId=this.scriptId allIds=controller.scriptIds}}{{this.title}}{{/view}}
+        </td>
+        <td>
+          <h4>
+            <span {{bind-attr class=":label jobSuccess:label-success jobError:label-danger jobInProgress:label-warning "}} class="label label-success">{{status}}</span>
+          </h4>
+        </td>
+        <td>{{#unless jobInProgress}}{{durationTime}}{{/unless}}</td>
+        <td>
+          {{#unless jobInProgress}}
+            <a {{action 'logsPopup' this}} href="#" title="Logs"> <i class="fa fa-file-text-o"></i></a>
+            <a {{action 'resultsPopup' this}} href="#" title="Results"> <i class="fa fa-table"></i></a>
+          {{/unless}}
+          <a href="#" {{action 'deleteJob' this}} title="Delete"><i class="fa fa-trash-o"></i></a>
+        </td>
+      </tr>
     {{/each}}
     </tbody>
   </table>
-
   {{#unless content}}
-    <div class="panel-footer empty-table-footer">{{t 'job.noJobs'}}</div>
+    <div class="alert alert-info" role="alert">{{t 'history.no_jobs_message'}}</div>
   {{/unless}}
 </div>
+
+{{#if content}}
+  {{partial 'partials/paginationControls'}}
+{{/if}}
+
+{{#if content}}
+  {{partial 'partials/paginationControls'}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs
deleted file mode 100644
index e3cbb1e..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs
+++ /dev/null
@@ -1,19 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs
deleted file mode 100644
index ed81a68..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs
+++ /dev/null
@@ -1,39 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="well well-sm">
-  <div class="jobStatus" style="margin-bottom: 5px;">
-    <small>
-    {{t 'job.job_status'}} <strong>{{content.status}}</strong>
-    </small>
-  </div>
-
-  {{#if content.needsPing}}
-    {{#unless content.isKilling}}
-      <button {{action "killjob" content}} type="button" class="btn btn-danger btn-xs kill-button">Kill</button>
-    {{/unless}}
-    {{#if content.isKilling}}
-      <div class="spinner-sm pull-left kill-button"></div>
-    {{/if}}
-  {{/if}}
-
-  {{view view.progressBar contentBinding="content"}}
-</div>
-
-
-{{outlet}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs
deleted file mode 100644
index 0efb5b2..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs
+++ /dev/null
@@ -1,18 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs
deleted file mode 100644
index 67c49bd..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs
+++ /dev/null
@@ -1,19 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-{{view view.outputView}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs
deleted file mode 100644
index 947b973..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs
+++ /dev/null
@@ -1,40 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="panel-heading">
-  <div class="btn-group" data-toggle="buttons" >
-    <label id='btn-stdout' {{action 'getOutput' 'stdout' target="view"}} {{bind-attr class=":btn :btn-success view.isLoadingOutput:disabled:" }} >
-      <input type="radio" name="options"> {{t  'job.job_results.stdout'}}
-    </label>
-    <label id='btn-stderr' {{action 'getOutput' 'stderr' target="view"}} {{bind-attr class=":btn :btn-danger view.isLoadingOutput:disabled:" }}>
-      <input type="radio" name="options"> {{t  'job.job_results.stderr'}}
-    </label>
-    <label id='btn-exitcode' {{action 'getOutput' 'exitcode' target="view"}} {{bind-attr class=":btn :btn-default view.isLoadingOutput:disabled:" }}>
-      <input type="radio" name="options"> {{t  'job.job_results.exitcode'}}
-    </label>
-  </div>
-</div>
-<div class="panel-body">
-
-  {{#unless view.isLoadingOutput}}
-    <pre>{{view.activeOutput}}</pre>
-  {{/unless}}
-  {{#if view.isLoadingOutput}}
-    <div class="spinner-sm"></div>
-  {{/if}}
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs
deleted file mode 100644
index 0efb5b2..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs
+++ /dev/null
@@ -1,18 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs
deleted file mode 100644
index 39e3a1c..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs
+++ /dev/null
@@ -1,29 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="modal-header">
-  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-  <h4 class="modal-title">{{t 'scripts.modal.confirm_delete'}}</h4>
-</div>
-<div class="modal-body">
-{{t 'scripts.modal.confirm_delete_massage' titleBinding="content.title" tagName="p"}}
-</div>
-<div class="modal-footer">
-  <button type="button" {{action "close" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'common.cancel'}}</button>
-  <button type="button" {{action "confirm" content target="view"}} class="btn btn-danger">{{t 'common.delete'}}</button>
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs
deleted file mode 100644
index 0d8d459..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs
+++ /dev/null
@@ -1,40 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="modal-header">
-  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-  <h4 class="modal-title">{{t 'scripts.modal.create_script'}}</h4>
-</div>
-<div class="modal-body">
-<div class="form-group">
-  {{#if error}}
-    <div class="alert alert-danger">{{error}}</div>
-  {{/if}}
-    <label for="exampleInputEmail1">{{t 'scripts.title'}}</label>
-    {{input class="form-control" placeholderTranslation="scripts.modal.script_title_placeholder" valueBinding="content.title"}}
-  </div>
-  <div class="form-group">
-    <label for="exampleInputPassword1">{{t 'scripts.path'}}</label>
-    {{input class="form-control" placeholderTranslation="scripts.modal.file_path_placeholder" valueBinding="filePath"}}
-    <small class="pull-right help-block">{{t 'scripts.modal.file_path_hint'}}</small>
-  </div>
-</div>
-<div class="modal-footer">
-  <button type="button" {{action "close" content target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
-  <button type="button" {{action "create" content target="view"}} {{bind-attr disabled="view.udfInvalid"}} class="btn btn-success">{{t 'common.create'}}</button>
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs
deleted file mode 100644
index a47ad1e..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs
+++ /dev/null
@@ -1,36 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="modal-header">
-  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-  <h4 class="modal-title">{{t 'udfs.modal.create_udf'}}</h4>
-</div>
-<div class="modal-body">
-<div class="form-group">
-    <label for="exampleInputEmail1">{{t 'common.name'}}</label>
-    {{input class="form-control" placeholderTranslation="udfs.modal.udf_name" valueBinding="content.name"}}
-  </div>
-  <div class="form-group">
-    <label for="exampleInputPassword1">{{t 'common.path'}}</label>
-    {{input class="form-control" placeholderTranslation="udfs.modal.hdfs_path" valueBinding="content.path"}}
-  </div>
-</div>
-<div class="modal-footer">
-  <button type="button" {{action "close" content target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
-  <button type="button" {{action "createUdf" content target="view"}} {{bind-attr disabled="view.udfInvalid"}} class="btn btn-success">{{t 'common.create'}}</button>
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs
deleted file mode 100644
index 79bebd9..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs
+++ /dev/null
@@ -1,25 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="modal fade in" data-backdrop="static">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      {{yield}}
-    </div><!-- /.modal-content -->
-  </div><!-- /.modal-dialog -->
-</div><!-- /.modal -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs
deleted file mode 100644
index a79d19f..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs
+++ /dev/null
@@ -1,167 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="edit-script">
-    <div {{bind-attr class=":panel :panel-editscript scriptError:panel-danger:panel-default"}} >
-      <div class="panel-heading">
-        <div class="head control-group">
-            {{outlet nav}}
-            {{#unless isRenaming}}
-              <div  {{bind-attr class="controller.isScript:input-group :input-title"}}>
-                {{input id="title" placeholderTranslation="scripts.title" class="form-control" disabled='disabled' valueBinding="content.title"}}
-                <div {{bind-attr class=":input-group-btn controller.isJob:hide"}}>
-                  <button  type="button" {{action 'rename' 'ask'}} {{bind-attr class=":btn :btn-default :btn-rename-ask"}} >
-                    <span class="glyphicon glyphicon-edit"></span>
-                  </button>
-                </div>
-              </div>
-            {{else}}
-              <div  {{bind-attr class=":input-group :input-title"}}>
-                {{input id="title" placeholderTranslation="scripts.title" class="form-control" valueBinding="content.title"}}
-                <div class="input-group-btn">
-                  <button  type="button" {{action 'rename' 'cancel'}} {{bind-attr class=":btn :btn-default :btn-rename-cancel"}} >
-                    <span class="glyphicon glyphicon-remove"></span> {{t 'common.cancel'}}
-                  </button>
-                </div>
-                <div class="input-group-btn">
-                  <button  type="button" {{action 'rename' 'confirm'}} {{bind-attr class=":btn :btn-primary :btn-rename-confirm"}} >
-                    <span class="glyphicon glyphicon-ok"></span> {{t 'editor.save'}}
-                  </button>
-                </div>
-              </div>
-            {{/unless}}
-        </div>
-      </div>
-      {{#if view.showEditor}}
-      <div class="panel-body" >
-        <div class="pull-left">
-        {{#if view.isEditConfirmed}}
-          {{view view.pigHelperView class="btn-group" }}
-          <div class="btn-group">
-              <button type="button" data-toggle="dropdown" {{bind-attr class=":btn :btn-default :btn-xs :dropdown-toggle ufdsList.length::disabled"}} >
-                {{t 'editor.udfhelper'}}
-                <span class="caret"></span>
-              </button>
-              <ul class="dropdown-menu">
-              {{#each ufdsList}}
-                <li><a href="#" {{action 'insertUdf' this target="view" }}>{{this.name}}</a></li>
-              {{/each}}
-              </ul>
-          </div>
-        {{/if}}
-        </div>
-        <kbd class="file-path pull-right" data-toggle="tooltip" data-placement="bottom"{{translateAttr title="udfs.tooltips.path"}} >
-          {{#unless content.pigScript.isLoaded}}
-            <div class="spinner-sm"></div>
-          {{/unless}}
-          {{#if content.pigScript.isLoaded}}
-            {{content.pigScript.id}}
-          {{/if}}
-        </kbd>
-      </div>
-      <div class="editor-container">
-        {{#if controller.isJob}}
-          {{#unless view.isEditConfirmed}}
-            <div class="edit-confirm">
-              <div class="well edit-confirm-container">
-                When you executed job, script was copied to another place in filesystem. <br />
-                You're going to edit the <u>copy of original script</u> from history<br />
-                <button {{action "confirmEdit" target="view"}} class="btn btn-large" type="button">Edit script from history</button>
-                {{#if content.scriptId}}
-                  <button {{action "returnToOriginal" content}} class="btn btn-large btn-primary" type="button">Return to original file</button>
-                {{/if}}
-              </div>
-            </div>
-          {{/unless}}
-        {{/if}}
-        {{view view.codeMirrorView id="pig_script" contentBinding="content.pigScript"}}
-      </div>
-      <div class="panel-footer" >
-        <span>
-          {{#with controller}}
-            {{#each controller.pigArgumentsPull}}
-              <span {{bind-attr class=":argument controller.isScript:editable:"}} >
-                <span class="title"> {{this}} </span>
-                {{#if controller.isScript}}
-                <button {{action "removeArgument" this}}  class="close rm-arg">
-                    &times;
-                </button>
-                {{/if}}
-              </span>
-            {{/each}}
-          {{/with}}
-          {{#if controller.isScript}}
-          {{view view.argumentInput placeholderTranslation="editor.pig_argument"}}
-            <button {{action "sendArgument" target="view.argumentInput" }} type="button" {{bind-attr class=":btn :btn-default :btn-xs view.argumentInput.value::disabled"}}>
-              <span class="glyphicon glyphicon-plus"></span> {{t 'common.add'}}
-            </button>
-          {{/if}}
-        </span>
-      </div>
-      {{else}}
-      <table class="table table-results">
-        <tr>
-          <td>{{t 'common.path'}}:</td>
-          <td><kbd>{{content.pigScript.id}}</kbd></td>
-        </tr>
-        <tr>
-          <td>{{t 'job.started'}}:</td>
-          <td>{{showDate content.dateStarted 'YYYY-MM-DD HH:mm'}}</td>
-        </tr>
-        <tr>
-          <td>{{t 'common.arguments'}}:</td>
-          <td>
-            {{#each pigArgumentsPull}}
-              <span {{bind-attr class=":argument controller.isScript:editable:"}} >
-                <span class="title"> {{this}} </span>
-              </span>
-            {{/each}}
-          </td>
-        </tr>
-      </table>
-      {{/if}}
-
-    </div>
-
-    {{outlet main}}
-
-    <div class="form-inline pigParams">
-    {{#each pigParams}}
-    <div class="form-group">
-      <label class="control-label">{{this.title}}</label>
-      <div class="">
-       {{view view.pigParamView class='form-control input-sm' valueBinding='value'}}
-      </div>
-    </div>
-    {{/each}}
-    </div>
-    {{#if view.showEditor}}
-    <div class="controls">
-      {{#unless isExec}}
-        <button {{action "execute" content 'execute' }} type="button" class="btn btn-default">{{t 'editor.execute'}}</button>
-        <button {{action "execute" content 'explain' }} type="button" class="btn btn-default">{{t 'editor.explain'}}</button>
-        <button {{action "execute" content 'syntax_check' }} type="button" class="btn btn-default">{{t 'editor.syntax_check'}}</button>
-        <input type="button" {{action "saveScript" content}} {{bind-attr class=":btn :btn-primary scriptDirty::disabled"}} {{translateAttr value="editor.save"}} >
-      {{/unless}}
-
-      {{#if isExec}}
-        <div class="spinner-sm"></div>
-      {{/if}}
-    </div>
-    {{/if}}
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs
deleted file mode 100644
index 0efb5b2..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs
+++ /dev/null
@@ -1,18 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs
deleted file mode 100644
index a460a71..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs
+++ /dev/null
@@ -1,62 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div class="panel panel-default panel-scriptlist">
-  <div class="panel-heading">
-    <span class="panel-title">
-      {{t 'scripts.scripts'}}
-    </span>
-    <a {{action "createScript"}} class="btn btn-default btn-sm pull-right new-script"><span class="glyphicon glyphicon-plus"></span> {{t 'scripts.newscript'}}</a>
-  </div>
-  
-  <table class="table table-bordered table-striped ">
-    <thead> 
-      <tr class="label-row"> 
-        <th class="first">{{t 'common.name'}}</th> 
-        <th>{{t 'common.created'}}</th> 
-        <th></th> 
-      </tr>
-    </thead>
-    <tbody>
-    {{#each content}}
-      <tr>
-
-        <td class="first">{{#link-to 'pig.scriptEdit' this.id}}
-          {{#if this.isNew}}
-            <div class="spinner-sm"></div>
-          {{/if}}
-          {{#unless this.isNew}}
-            {{this.title}}
-          {{/unless}}
-        {{/link-to}}</td>
-        <td><span class="date">{{showDate this.dateCreated 'YYYY-MM-DD HH:mm'}}</span></td>
-        <td>
-          {{#unless this.isNew}}
-            <a href="#" {{action "deletescript" this}}>{{t 'common.delete'}}</a>
-          {{/unless}}
-        </td>
-      </tr>
-    {{/each}}
-    </tbody>
-  </table>
-  {{#unless content}}
-    <div class="panel-footer empty-table-footer">{{t 'scripts.noScripts'}}</div>
-  {{/unless}}
-</div>
-
-{{outlet modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs
deleted file mode 100644
index 0efb5b2..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs
+++ /dev/null
@@ -1,18 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs
deleted file mode 100644
index a94716f..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs
+++ /dev/null
@@ -1,19 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-{{view view.navResultsView }}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scripts.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scripts.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scripts.hbs
new file mode 100644
index 0000000..fa65171
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scripts.hbs
@@ -0,0 +1,86 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="scriptlist">
+  <div class="title-row">
+    <h3 class="pull-left">{{t 'scripts.scripts'}}</h3>
+    <a {{action "createScript"}} class="btn btn-default pull-right new-script"><i class="fa fa-plus"></i> {{t 'scripts.newscript'}}</a>
+  </div>
+  <table class="table table-striped ">
+    <thead>
+      <tr class="label-row">
+        <th class="first">{{t 'common.name'}}</th>
+        <th>{{t 'scripts.last_executed'}}</th>
+        <th>{{t 'scripts.last_results'}}</th>
+        <th>{{t 'common.actions'}}</th>
+      </tr>
+    </thead>
+    <tbody>
+    {{#each paginatedContent}}
+      {{#script-list-row script=this jobs=controller.jobs}}
+        <td class="first">{{#link-to 'script.edit' id}}
+          {{#if isNew}}
+            <div class="spinner-sm"></div>
+          {{/if}}
+          {{#unless isNew}}
+            {{title}}
+          {{/unless}}
+        {{/link-to}}
+        </td>
+        <td>
+          {{#if view.currentJob}}
+            <span class="date">{{showDate view.currentJob.dateStarted 'YYYY-MM-DD HH:mm'}}</span>
+          {{else}}
+            {{t 'scripts.not_run_message'}}
+          {{/if}}
+        </td>
+        <td>
+        {{#if view.currentJob.jobInProgress}}
+          <h4>
+            <span class="label label-warning">{{view.currentJob.status}}</span>
+          </h4>
+        {{/if}}
+        {{#if view.currentJob.jobSuccess}}
+          <i class="fa fa-fw fa-lg fa-check green"></i> {{t 'common.success'}} <small> ({{view.currentJob.durationTime}})</small>
+        {{/if}}
+        {{#if view.currentJob.jobError}}
+          <i class="fa fa-fw fa-lg fa-exclamation red"></i> {{t 'common.error'}}
+        {{/if}}
+        </td>
+        <td>
+          {{#unless isNew}}
+            {{#link-to 'script.history' id}}<i class="fa fa-clock-o"></i> {{t 'common.history'}}{{/link-to}}
+            <a href="#" {{action "copyScript" this}}><i class="fa fa-copy"></i> {{t 'common.copy'}}</a>
+            <a href="#" {{action "deletescript" this}}><i class="fa fa-trash-o"></i> {{t 'common.delete'}}</a>
+          {{/unless}}
+        </td>
+      {{/script-list-row}}
+    {{/each}}
+    </tbody>
+  </table>
+
+  {{#if content}}
+    {{partial 'partials/paginationControls'}}
+  {{/if}}
+
+  {{#unless content}}
+    <div class="alert alert-info" role="alert">{{t 'scripts.noScripts'}}</div>
+  {{/unless}}
+</div>
+
+{{outlet modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
index 473c41d..ff901b6 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
@@ -16,15 +16,12 @@
    limitations under the License.
 }}
 
-<div class="panel panel-default panel-udfs">
-  <div class="panel-heading">
-    <span class="panel-title">
-      {{t 'udfs.udfs'}}
-    </span>
-    <a {{action "createUdfModal"}} class="btn btn-default btn-sm pull-right upload-udf"><span class="glyphicon glyphicon-plus"></span> {{t 'common.create'}}</a>
+<div class="panel-udfs">
+  <div class="title-row">
+    <h3 class="pull-left">{{t 'udfs.udfs'}}</h3>
+    <a {{action "createUdfModal"}} class="btn btn-default pull-right upload-udf"><span class="glyphicon glyphicon-plus"></span> {{t 'udfs.create'}}</a>
   </div>
-  
-  <table class="table table-bordered table-striped">
+  <table class="table table-striped">
     <thead> 
       <tr class="label-row">
         <th class="first">{{t 'common.name'}}</th> 
@@ -34,7 +31,7 @@
       </tr>
     </thead>
     <tbody>
-    {{#each content}}
+    {{#each paginatedContent}}
         <tr> 
           <td> {{this.name}}</td>
           <td> {{this.path}}</td>
@@ -45,7 +42,12 @@
     </tbody>
   </table>
 
+  {{#if content}}
+    {{partial 'partials/paginationControls'}}
+  {{/if}}
+
   {{#unless content}}
-    <div class="panel-footer empty-table-footer">{{t 'udfs.noUDFs'}}</div>
+    <div class="alert alert-info" role="alert">{{t 'udfs.noUDFs'}}</div>
   {{/unless}}
-</div>
+
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs
deleted file mode 100644
index fed326d..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs
+++ /dev/null
@@ -1,25 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-  <button type="button" class="close" >&times;</button>
-  <p>
-    {{view.content.message}}
-  </p>
-  {{#if view.content.trace}}
-      <a href="#" {{action 'showErrorLog' this}}>{{t 'common.showErrorLog'}}</a>
-  {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs
deleted file mode 100644
index 8ee2dfb..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs
+++ /dev/null
@@ -1,21 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<div id="alert-wrap">
-   {{view view.alertsView}}
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs
deleted file mode 100644
index 29b033d..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs
+++ /dev/null
@@ -1,34 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
-  {{t 'editor.pighelper'}}
-  <span class="caret"></span>
-</button>
-<ul class="dropdown-menu" id="pig_helper">
-  {{#each view.helpers}}
-    <li class="dropdown-submenu">
-      <a>{{this.title}}</a>
-      <ul class="dropdown-menu">
-        {{#each this.helpers }}
-          <li><a href="#" {{action 'putToEditor' this target="view" }} >{{this}}</a></li>
-        {{/each}}
-      </ul>
-    </li>
-  {{/each}}
-</ul>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs
deleted file mode 100644
index 767ad5f..0000000
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs
+++ /dev/null
@@ -1,30 +0,0 @@
-{{!
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-  
-       http://www.apache.org/licenses/LICENSE-2.0
-  
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-}}
-
-<span class='lb' {{action "gotoSection" view.content }}>
-{{view.content.label}}
-
-{{#unless view.content.label}}
-...     
-{{/unless}} 
-	
-</span>
-  
-{{#if view.content.id}} 
-  <button {{action "close" view.content }}type="button" class="close rm" >&times;</button>
-{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script.hbs
new file mode 100644
index 0000000..e854fa0
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script.hbs
@@ -0,0 +1,27 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<ul class="nav nav-tabs nav-tabs-script" role="tablist">
+  {{#each tabs}}
+    {{#tab-control tab=name current=controller.activeTab popTab='deactivateJob'  target=target}}
+      {{#link-to url target disabled=view.disabled}}{{label}}{{/link-to}}
+    {{/tab-control}}
+  {{/each}}
+</ul>
+
+{{outlet}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/edit.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/edit.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/edit.hbs
new file mode 100644
index 0000000..95d830b
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/edit.hbs
@@ -0,0 +1,146 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="edit-script">
+  <div {{bind-attr class=":panel :panel-editscript scriptError:panel-danger:panel-default"}} >
+    <div class="panel-heading">
+      {{outlet nav}}
+      {{#unless isExec}}
+        <div {{bind-attr class=":btn-group :pull-right isRenaming:hide"}}>
+          <button {{action "execute" content 'execute' }} type="button" class="btn btn-primary">{{t 'editor.execute'}}</button>
+
+          <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
+            <span class="caret"></span>
+            <span class="sr-only">Toggle Dropdown</span>
+          </button>
+          <ul class="dropdown-menu" role="menu">
+            <li><a href="#" {{action "execute" content 'explain' }} >{{t 'editor.explain'}}</a></li>
+            <li><a href="#" {{action "execute" content 'syntax_check' }} >{{t 'editor.syntax_check'}}</a></li>
+          </ul>
+        </div>
+        {{else}}
+        <div class="spinner-sm pull-right"></div>
+      {{/unless}}
+      {{#unless isRenaming}}
+
+        <div class="script-title">
+          <h4> {{content.title}} <a href="#" {{action 'rename' 'ask'}} class="btn-rename"><i class="fa fa-pencil"></i></a></h4>
+        </div>
+
+      {{else}}
+        <div  {{bind-attr class=":input-group :input-title titleWarn:has-error"}}>
+          {{input
+            id="title"
+            placeholderTranslation="scripts.modal.script_title_placeholder"
+            class="form-control"
+            valueBinding="content.title"
+          }}
+          <div class="input-group-btn">
+            <button  type="button" {{action 'rename' 'cancel'}} {{bind-attr class=":btn :btn-default :btn-rename-cancel"}} >
+              <i class="fa fa-lg fa-remove"></i> <span class="hidden-xs">{{t 'common.cancel'}}</span>
+            </button>
+          </div>
+          <div class="input-group-btn">
+            <button  type="button" {{action 'rename' 'confirm'}} {{bind-attr class=":btn :btn-success :btn-rename-confirm content.title::disabled"}} >
+              <i class="fa fa-lg fa-check"></i> <span class="hidden-xs">{{t 'editor.save'}}</span>
+            </button>
+          </div>
+        </div>
+      {{/unless}}
+
+    </div>
+    <div class="panel-body" >
+      <div class="pull-left">
+      {{pig-helper class="btn-group" editor=editor}}
+        <div class="btn-group">
+          <button type="button" data-toggle="dropdown" {{bind-attr class=":btn :btn-default :btn-xs :dropdown-toggle ufdsList.length::disabled"}} >
+            {{t 'editor.udfhelper'}}
+            <span class="caret"></span>
+          </button>
+          <ul class="dropdown-menu">
+          {{#each ufdsList}}
+            <li><a href="#" {{action 'insertUdf' this target="view" }}>{{this.name}}</a></li>
+          {{/each}}
+          </ul>
+        </div>
+      </div>
+      <kbd class="file-path pull-right" data-toggle="tooltip" data-placement="bottom"{{translateAttr title="udfs.tooltips.path"}} >
+        {{#unless content.pigScript.isLoaded}}
+          <div class="spinner-sm"></div>
+        {{else}}
+          {{content.pigScript.id}}
+        {{/unless}}
+      </kbd>
+    </div>
+    <div class="editor-container">
+      {{code-mirror id="pig_script" content=content.pigScript codeMirror=editor}}
+      <div class="ui-resizable-handle ui-resizable-s" id="sgrip"><i class="fa fa-ellipsis-h"></i></div>
+    </div>
+  </div>
+
+
+  <div {{bind-attr class=":params-block pigParams::hidden"}}>
+    <div class="block-title">
+      <h4>{{t 'editor.params'}}</h4>
+    </div>
+    <div class="form-inline pigParams">
+    {{#each pigParams}}
+      <div class="form-group">
+        <label class="control-label">{{this.title}}</label>
+        <div class="">
+         {{input class='form-control input-sm' valueBinding='value'}}
+        </div>
+      </div>
+    {{/each}}
+    </div>
+  </div>
+
+  <div class="arguments-block">
+    <div class="block-title">
+      <h4>{{t 'editor.arguments'}}</h4>
+    </div>
+    <div class="row">
+      <div class="col-md-8 ">
+        {{#if argumentsArray}}
+
+        <div class="arguments-wrap">
+          {{#each argumentsArray}}
+            <span class="label label-primary"> <span class="pull-left" >{{this}}</span>  <a href="#" {{action "removeArgument" this}} {{bind-attr class=":close :rm-arg"}}><i class="fa fa-remove"></i></a> </span>
+          {{/each}}
+        </div>
+        {{else}}
+          <div class="alert alert-info" role="alert">
+            {{t 'editor.no_arguments_message'}}
+          </div>
+        {{/if}}
+      </div>
+      <div class="col-md-4 ">
+        <div class="input-group">
+          {{input action="addArgument" placeholderTranslation="editor.pig_argument" class="form-control" valueBinding='tmpArgument'}}
+          <span class="input-group-btn">
+            <button class="btn btn-default pull-right" {{action 'addArgument'}} ><i class="fa fa-plus"></i> {{t 'common.add'}}</button>
+          </span>
+        </div>
+      </div>
+
+    </div>
+  </div>
+
+  {{outlet main}}
+
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/history.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/history.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/history.hbs
new file mode 100644
index 0000000..8f0ca34
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/history.hbs
@@ -0,0 +1,61 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="script_history_container">
+  <table class="table table-striped">
+    <thead>
+      <tr>
+          <th>{{t 'common.date'}}</th>
+          <th>{{t 'job.status'}}</th>
+          <th>{{t 'history.duration'}}</th>
+          <th>{{t 'common.actions'}}</th>
+      </tr>
+          <th>{{t 'common.date'}}</th>
+          <th>{{t 'job.status'}}</th>
+          <th>{{t 'history.duration'}}</th>
+          <th>{{t 'common.actions'}}</th>
+      </tr>
+    </thead>
+    <tbody>
+      {{#each paginatedContent}}
+        <tr>
+          <td>{{#link-to 'script.job' id}}{{showDate dateStarted 'YYYY-MM-DD HH:mm'}}{{/link-to}}</td>
+          <td>
+            <h4>
+              <span {{bind-attr class=":label jobSuccess:label-success jobError:label-danger jobInProgress:label-warning "}} class="label label-success">{{status}}</span>
+            </h4>
+          </td>
+          <td>{{#unless jobInProgress}}{{durationTime}}{{/unless}}</td>
+          <td>
+            {{#unless jobInProgress}}
+              <a {{action 'logsPopup' this}} href="#"> <i class="fa fa-file-text-o"></i> {{t 'job.logs'}}</a>
+              <a {{action 'resultsPopup' this}} href="#"> <i class="fa fa-table"></i> {{t 'job.results'}}</a>
+            {{/unless}}
+            <a href="#" {{action 'deleteJob' this}}><i class="fa fa-trash-o"></i> {{t 'common.delete'}}</a>
+          </td>
+        </tr>
+      {{/each}}
+    </tbody>
+  </table>
+</div>
+{{#unless content}}
+  <div class="alert alert-info" role="alert">{{t 'scripts.no_jobs_message'}}</div>
+{{/unless}}
+{{#if content}}
+  {{partial 'partials/paginationControls'}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/job.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/job.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/job.hbs
new file mode 100644
index 0000000..bf406a9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/script/job.hbs
@@ -0,0 +1,153 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+<div class="job-container">
+  <h3>
+    {{title}} - <span {{bind-attr class=":label jobSuccess:label-success jobError:label-danger jobInProgress:label-warning "}}>{{status}}</span>
+  </h3>
+
+    <div class="row">
+
+      <div {{bind-attr class="needsPing:col-md-10:col-md-12 :progress-wrap" }} >
+        {{job-progress job=content}}
+      </div>
+      {{#if needsPing}}
+        <div class="col-md-2">
+          {{#unless isKilling}}
+            <button {{action "killjob" content}} type="button" class="btn btn-block btn-danger btn-sm kill-button"><i class="fa fa-times"></i> {{t 'job.kill_job'}}</button>
+          {{/unless}}
+          {{#if isKilling}}
+            <div class="spinner-sm pull-left kill-button"></div>
+          {{/if}}
+        </div>
+      {{/if}}
+    </div>
+
+  <table class="table job-info">
+    <tbody>
+      <tr>
+        <td>{{t 'job.jobId'}}</td>
+        <td>{{jobId}}</td>
+      </tr>
+      <tr>
+        <td>{{t 'job.started'}}</td>
+        <td>{{showDate dateStarted 'YYYY-MM-DD HH:mm'}}</td>
+      </tr>
+    </tbody>
+  </table>
+
+  {{#unless jobInProgress}}
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <h4 class="panel-title">
+          <a data-toggle="collapse" href="#scriptResults">
+            <i class="toggle-icon fa fa-fw fa-chevron-right"></i>
+            {{t 'job.results'}}
+          </a>
+          {{#if jobResults.isFulfilled }}
+          <p class="pull-right" ><a href="#" {{action 'download' 'results'}}><i class="fa fa-download"></i> {{t 'common.download'}}</a></p>
+          {{/if}}
+        </h4>
+      </div>
+      {{#view "view.collapsePanel" id="scriptResults" class="panel-collapse collapse" }}
+        <div class="panel-body">
+        {{#if jobResults.isPending}}
+          <pre><div class="spinner-sm"></div></pre>
+        {{else}}
+          {{#if jobResults.isFulfilled }}
+          <pre>{{jobResults.content.fileContent}}</pre>
+          {{/if}}
+          {{#if jobResults.isRejected}}
+            {{jobResults.reason}}
+          {{/if}}
+        {{/if}}
+        </div>
+      {{/view}}
+    </div>
+
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <h4 class="panel-title">
+          <a data-toggle="collapse" href="#scriptLogs">
+            <i class="toggle-icon fa fa-fw fa-chevron-right"></i>
+            {{t 'job.logs'}}
+          </a>
+          {{#if jobLogs.isFulfilled}}
+          <p class="pull-right" ><a href="#" {{action 'download' 'logs'}}><i class="fa fa-download"></i> {{t 'common.download'}}</a></p>
+          {{/if}}
+        </h4>
+      </div>
+      {{#view "view.collapsePanel" id="scriptLogs" class="panel-collapse collapse"}}
+        <div class="panel-body">
+        {{#if jobLogs.isPending}}
+          <pre><div class="spinner-sm"></div></pre>
+        {{else}}
+          {{#if jobLogs.isFulfilled}}
+          <pre>{{jobLogs.content.fileContent}}</pre>
+          {{/if}}
+          {{#if jobLogs.isRejected}}
+            {{jobLogs.reason}}
+          {{/if}}
+        {{/if}}
+        </div>
+      {{/view}}
+    </div>
+  {{/unless}}
+
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <h4 class="panel-title">
+          <a data-toggle="collapse" href="#scriptDetails">
+            <i class="toggle-icon fa fa-fw fa-chevron-right fa-rotate-90"></i>
+            {{t 'job.script_details'}}
+          </a>
+        </h4>
+      </div>
+      {{#view "view.collapsePanel" id="scriptDetails" class="panel-collapse collapse in" }}
+        <div class="panel-body body-title">
+          {{t 'job.script_contents'}}:
+        </div>
+          {{#if scriptContents.isPending}}
+            <div class="panel-body">
+              <div class="spinner-sm"></div>
+            </div>
+          {{else}}
+            {{#if scriptContents.isFulfilled}}
+              <div class="editor-container">
+                {{code-mirror id="pig_script" content=scriptContents readOnly=true}}
+                <div class="ui-resizable-handle ui-resizable-s" id="sgrip"><i class="fa fa-ellipsis-h"></i></div>
+              </div>
+            {{else}}
+              {{#if scriptContents.isRejected}}
+                <div class="alert alert-danger" role="alert">
+                 {{scriptContents.reason}}
+                </div>
+              {{/if}}
+            {{/if}}
+          {{/if}}
+        <div class="panel-body body-title">
+          {{t 'common.arguments'}}:
+        </div>
+        <div class="panel-body arguments-wrap">
+          {{#each argumentsArray}}
+            <span class="label label-primary">{{this}}</span>
+          {{/each}}
+        </div>
+      {{/view}}
+    </div>
+
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/splash.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/splash.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/splash.hbs
index 73fdaef..7455a4f 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/splash.hbs
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/splash.hbs
@@ -17,8 +17,8 @@
 }}
 
 <div class="container-fluid">
-  <h1>Welcome to Apache Pig UI</h1>
-  <h2>Please wait while we test connection to services</h2>
+  <h1>{{t 'splash.welcome'}}</h1>
+  <h2>{{t 'splash.please_wait'}}</h2>
 
   <div class="progress progress-striped active">
     <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" {{bind-attr style="progressBarStyle"}}>
@@ -39,37 +39,37 @@
             <span class="glyphicon glyphicon-arrow-right"></span>
           {{/if}}
         </td>
-        <td>Storage test</td>
+        <td>{{t 'splash.storage_test'}}</td>
       </tr>
 
       <tr>
-          <td>
-            {{#if hdfsTestDone}}
-              {{#if hdfsTest}}
-                  <span class="glyphicon glyphicon-ok green"></span>
-              {{else}}
-                  <span class="glyphicon glyphicon-remove red"></span>
-              {{/if}}
+        <td>
+          {{#if hdfsTestDone}}
+            {{#if hdfsTest}}
+              <span class="glyphicon glyphicon-ok green"></span>
             {{else}}
-                <span class="glyphicon glyphicon-arrow-right"></span>
+              <span class="glyphicon glyphicon-remove red"></span>
             {{/if}}
-          </td>
-          <td>HDFS test</td>
+          {{else}}
+            <span class="glyphicon glyphicon-arrow-right"></span>
+          {{/if}}
+        </td>
+        <td>{{t 'splash.hdfs_test'}}</td>
       </tr>
 
       <tr>
-          <td>
-            {{#if webhcatTestDone}}
-              {{#if webhcatTest}}
-                  <span class="glyphicon glyphicon-ok green"></span>
-              {{else}}
-                  <span class="glyphicon glyphicon-remove red"></span>
-              {{/if}}
+        <td>
+          {{#if webhcatTestDone}}
+            {{#if webhcatTest}}
+                <span class="glyphicon glyphicon-ok green"></span>
             {{else}}
-                <span class="glyphicon glyphicon-arrow-right"></span>
+                <span class="glyphicon glyphicon-remove red"></span>
             {{/if}}
-          </td>
-          <td>WebHCat test</td>
+          {{else}}
+              <span class="glyphicon glyphicon-arrow-right"></span>
+          {{/if}}
+        </td>
+        <td>{{t 'splash.webhcat_test'}}</td>
       </tr>
 
     </tbody>
@@ -80,17 +80,17 @@
   <p>{{{errors}}}</p>
   {{/if}}
   {{#if stackTrace}}
-      <a href="#" {{action "toggleStackTrace" post}}>
-        {{#if isExpanded}}
-            <span class="glyphicon glyphicon-collapse-down"></span> Collapse Stack Trace
-        {{else}}
-            <span class="glyphicon glyphicon-expand"></span> Expand Stack Trace
-        {{/if}}
-      </a>
+    <a href="#" {{action "toggleStackTrace" post}}>
+      {{#if isExpanded}}
+          <span class="glyphicon glyphicon-collapse-down"></span> Collapse Stack Trace
+      {{else}}
+          <span class="glyphicon glyphicon-expand"></span> Expand Stack Trace
+      {{/if}}
+    </a>
     {{#if isExpanded}}
-        <pre class="prettyprint">
-{{stackTrace}}
-        </pre>
+      <pre class="prettyprint">
+        {{stackTrace}}
+      </pre>
     {{/if}}
   {{/if}}
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
index f59102b..e1bb083 100644
--- a/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
@@ -24,28 +24,47 @@ Ember.I18n.translations = {
     'name':"Name",
     'path':"Path",
     'owner':"Owner",
+    'save':"Save",
     'delete':"Delete",
     'created':"Created",
-    'created':"Created",
     'history':"History",
     'clone':"Clone",
     'cancel':"Cancel",
+    'discard_changes':"Discard changes",
     'arguments':"Arguments",
     'errorLog':"Stack Trace",
-    'showErrorLog':"Show Stack Trace"
+    'showErrorLog':"Show Stack Trace",
+    'warning':"Warning",
+    'close':"Close",
+    'download':"Download",
+    'show':'Show:',
+    'actions':'Actions',
+    'date':'Date',
+    'success':'Success',
+    'error':'Error',
+    'copy':'Copy'
   },
   'scripts':{
+    'script':"Script",
     'scripts':"Scripts",
     'newscript': "New Script",
     'title': "Name",
     'path': "Script HDFS Location (optional)",
-    'noScripts': "No scripts to display",
+    'not_run_message': "Not run",
+    'noScripts': "No pig scripts have been created. To get started, click New Script.",
+    'last_executed':'Last Executed',
+    'last_results':'Last Results',
+    'no_jobs_message':'This script has not been executed',
     'modal':{
       'create_script':'New Script',
+      'unsaved_changes_warning':'You have unsaved changes in script.',
       'script_title_placeholder': 'Script name',
       'file_path_placeholder':'Full path to script file',
       'file_path_hint':'Leave empty to create file automatically.',
-      'file_path_hint':'Leave empty to create file automatically.',
+      'copy_created_massage':'{{title}} created successfully.',
+      'copy_created':'Copy Created',
+      'continue_editing':'Continue Editing',
+      'go_to_copy':'Go to Copy',
 
       'error_empty_title':'Title can not be empty!',
 
@@ -63,14 +82,19 @@ Ember.I18n.translations = {
       'delete_failed':'Delete failed!',
       'save_error':'Error while saving script',
       'save_error_reason':'{{message}}',
-    },
+      'rename_unfinished':'Please rename script first.'
+    }
   },
   'editor':{
     'title_updated':'Title updated.',
     'pig_argument':'Pig argument',
     'pighelper':'PIG helper',
     'udfhelper':'UDF helper',
+    'actions':'Actions',
     'save':'Save',
+    'params':'Params',
+    'arguments':'Arguments',
+    'no_arguments_message':'This pig script has no arguments defined.',
     'execute':'Execute',
     'explain':'Explain',
     'syntax_check':'Syntax check'
@@ -82,8 +106,12 @@ Ember.I18n.translations = {
     'logs':'Logs',
     'job_status':'Job status: ',
     'status':'Status',
-    'started':'Date started',
+    'jobId':'Job ID',
+    'started':'Started',
     'noJobs': "No jobs to display",
+    'kill_job': "Kill job",
+    'script_details': "Script Details",
+    'script_contents': "Script contents",
     'alert':{
       'job_started' :'Job started!',
       'job_killed' :'{{title}} job killed!',
@@ -93,6 +121,9 @@ Ember.I18n.translations = {
       'stdout_error' :'Error loading STDOUT. \n Status: {{status}} Message: {{message}}',
       'stderr_error' :'Error loading STDERR. \n Status: {{status}} Message: {{message}}',
       'exit_error' :'Error loading EXITCODE. \n Status: {{status}} Message: {{message}}',
+      'promise_error' :'Error loading file. \n Status: {{status}} Message: {{message}}',
+      'job_deleted' :'Job deleted successfully',
+      'delete_filed' :'Failed to delete job'
     },
     'job_results':{
       'stdout':'Stdout',
@@ -100,25 +131,41 @@ Ember.I18n.translations = {
       'exitcode':'Exit code',
       'stdout_loading':'Loading stdout...',
       'stderr_loading':'Loading stderr...',
-      'exitcode_loading':'Loading exitcode...',
+      'exitcode_loading':'Loading exitcode...'
     },
+    'modal':{
+      'confirm_delete_massage':'Are you sure you want to delete {{title}} job?'
+    }
   },
   'udfs':{
     'udfs':'UDFs',
+    'create':'Create UDF',
     'tooltips':{
-      'path':'Path of this script file on HDFS',
+      'path':'Path of this script file on HDFS'
     },
     'noUDFs': "No UDFs to display",
     'alert':{
       'udf_created':'{{name}} created!',
       'udf_deleted':'{{name}} deleted!',
       'create_failed':'Failed to create UDF!',
-      'delete_failed':'Delete failed!',
+      'delete_failed':'Delete failed!'
     },
     'modal':{
       'create_udf':'Create UDF',
       'udf_name':'UDF name',
-      'hdfs_path':'HDFS path',
+      'hdfs_path':'HDFS path'
     }
+  },
+  'history':{
+    'duration':'Duration',
+    'no_jobs_message':'No jobs was run',
+    'load_error':'Error loading pig history.'
+  },
+  'splash':{
+    'welcome':'Welcome to Apache Pig UI',
+    'please_wait':'Please wait while we test connection to services',
+    'storage_test':'Storage test',
+    'hdfs_test':'HDFS test',
+    'webhcat_test':'WebHCat test'
   }
 };


[10/10] ambari git commit: AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)

Posted by al...@apache.org.
AMBARI-8402. View: Pig ui updates + flow changes (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/82e72e51
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/82e72e51
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/82e72e51

Branch: refs/heads/trunk
Commit: 82e72e517f3b86db25d2026b53b77c5c72fa8eab
Parents: bf19364
Author: Alex Antonenko <hi...@gmail.com>
Authored: Mon Nov 24 20:20:32 2014 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue Nov 25 19:13:19 2014 +0200

----------------------------------------------------------------------
 contrib/views/pig/pom.xml                       |    1 -
 .../view/pig/persistence/DataStoreStorage.java  |  174 +++
 .../persistence/InstanceKeyValueStorage.java    |    4 +-
 .../pig/persistence/LocalKeyValueStorage.java   |    1 +
 .../persistence/PersistentConfiguration.java    |    1 +
 .../ambari/view/pig/persistence/Storage.java    |    2 +-
 .../utils/ContextConfigurationAdapter.java      |    5 +-
 .../view/pig/persistence/utils/StorageUtil.java |   35 +-
 .../view/pig/resources/CRUDResourceManager.java |    2 +-
 .../resources/PersonalCRUDResourceManager.java  |   16 +-
 .../view/pig/resources/files/FileService.java   |    2 +-
 .../pig/resources/jobs/JobResourceManager.java  |  113 +-
 .../view/pig/resources/jobs/JobService.java     |   26 +-
 .../view/pig/resources/jobs/models/PigJob.java  |   48 +-
 .../pig/resources/jobs/utils/JobPolling.java    |   99 +-
 .../scripts/ScriptResourceManager.java          |   12 +-
 .../pig/resources/scripts/ScriptService.java    |    2 +-
 .../ambari/view/pig/services/BaseService.java   |   57 +-
 .../ambari/view/pig/services/HelpService.java   |    7 +-
 .../view/pig/templeton/client/Request.java      |   24 +-
 .../view/pig/templeton/client/TempletonApi.java |    2 +-
 .../ambari/view/pig/utils/FilePaginator.java    |    2 +-
 .../apache/ambari/view/pig/utils/HdfsApi.java   |   60 +
 .../ui/pig-web/app/assets/data/pigHelpers.json  |  128 ++
 .../app/assets/static/fonts/FontAwesome.otf     |  Bin 0 -> 85908 bytes
 .../assets/static/fonts/fontawesome-webfont.eot |  Bin 0 -> 56006 bytes
 .../assets/static/fonts/fontawesome-webfont.svg |  520 ++++++++
 .../assets/static/fonts/fontawesome-webfont.ttf |  Bin 0 -> 112160 bytes
 .../static/fonts/fontawesome-webfont.woff       |  Bin 0 -> 65452 bytes
 .../ui/pig-web/app/components/codeMirror.js     |   83 ++
 .../ui/pig-web/app/components/helpers-data.js   |  146 +++
 .../ui/pig-web/app/components/jobProgress.js    |   32 +
 .../ui/pig-web/app/components/pigHelper.js      |   54 +
 .../ui/pig-web/app/components/scriptListRow.js  |   39 +
 .../ui/pig-web/app/components/tabControl.js     |   44 +
 .../ui/pig-web/app/controllers/edit.js          |  195 ---
 .../ui/pig-web/app/controllers/errorLog.js      |    2 +-
 .../ui/pig-web/app/controllers/jobResults.js    |   58 -
 .../app/controllers/modal/confirmAway.js        |   47 +
 .../app/controllers/modal/confirmDelete.js      |   28 +
 .../app/controllers/modal/createScript.js       |   52 +
 .../pig-web/app/controllers/modal/createUdf.js  |   34 +
 .../pig-web/app/controllers/modal/deleteJob.js  |   28 +
 .../pig-web/app/controllers/modal/gotoCopy.js   |   28 +
 .../app/controllers/modal/logDownload.js        |   42 +
 .../pig-web/app/controllers/modal/pigModal.js   |   41 +-
 .../app/controllers/modal/resultsDownload.js    |   42 +
 .../ui/pig-web/app/controllers/page.js          |   27 +
 .../resources/ui/pig-web/app/controllers/pig.js |   83 +-
 .../ui/pig-web/app/controllers/pigAlert.js      |   34 +
 .../ui/pig-web/app/controllers/pigHistory.js    |   26 +-
 .../ui/pig-web/app/controllers/pigJob.js        |   31 -
 .../ui/pig-web/app/controllers/pigScriptEdit.js |   68 -
 .../app/controllers/pigScriptEditResults.js     |   22 -
 .../ui/pig-web/app/controllers/pigScriptList.js |   23 -
 .../ui/pig-web/app/controllers/pigScripts.js    |   84 ++
 .../ui/pig-web/app/controllers/pigUdfs.js       |   48 +-
 .../ui/pig-web/app/controllers/poll.js          |   59 -
 .../ui/pig-web/app/controllers/script.js        |  117 ++
 .../ui/pig-web/app/controllers/scriptEdit.js    |  208 +++
 .../ui/pig-web/app/controllers/scriptHistory.js |   35 +
 .../ui/pig-web/app/controllers/scriptJob.js     |   65 +
 .../app/controllers/util/pigUtilAlert.js        |   34 -
 .../main/resources/ui/pig-web/app/initialize.js |  217 ++--
 .../ui/pig-web/app/mixins/fileHandler.js        |   54 +
 .../ui/pig-web/app/mixins/pagination.js         |   99 ++
 .../resources/ui/pig-web/app/models/pig_job.js  |   31 +-
 .../ui/pig-web/app/models/pig_script.js         |   29 +-
 .../src/main/resources/ui/pig-web/app/router.js |   13 +-
 .../ui/pig-web/app/routes/jobResults.js         |   29 -
 .../main/resources/ui/pig-web/app/routes/pig.js |   55 +-
 .../ui/pig-web/app/routes/pigHistory.js         |   14 +
 .../resources/ui/pig-web/app/routes/pigIndex.js |   25 -
 .../resources/ui/pig-web/app/routes/pigJob.js   |   57 -
 .../ui/pig-web/app/routes/pigScriptEdit.js      |   74 --
 .../ui/pig-web/app/routes/pigScriptEditIndex.js |   27 -
 .../pig-web/app/routes/pigScriptEditResults.js  |   36 -
 .../ui/pig-web/app/routes/pigScriptList.js      |   93 --
 .../ui/pig-web/app/routes/pigScripts.js         |   28 +
 .../resources/ui/pig-web/app/routes/pigUdfs.js  |   33 -
 .../resources/ui/pig-web/app/routes/script.js   |   59 +
 .../ui/pig-web/app/routes/scriptEdit.js         |   47 +
 .../ui/pig-web/app/routes/scriptHistory.js      |   36 +
 .../ui/pig-web/app/routes/scriptJob.js          |   58 +
 .../resources/ui/pig-web/app/routes/splash.js   |   18 +-
 .../resources/ui/pig-web/app/styles/style.less  |  465 ++++++-
 .../app/templates/components/pigHelper.hbs      |   34 +
 .../app/templates/components/scriptListRow.hbs  |   44 +
 .../ui/pig-web/app/templates/error.hbs          |   35 +
 .../ui/pig-web/app/templates/index.hbs          |   18 -
 .../pig-web/app/templates/modal/confirmAway.hbs |   32 +
 .../app/templates/modal/confirmDelete.hbs       |   31 +
 .../app/templates/modal/createScript.hbs        |   42 +
 .../pig-web/app/templates/modal/createUdf.hbs   |   38 +
 .../pig-web/app/templates/modal/deleteJob.hbs   |   31 +
 .../ui/pig-web/app/templates/modal/gotoCopy.hbs |   31 +
 .../pig-web/app/templates/modal/logDownload.hbs |   42 +
 .../pig-web/app/templates/modal/modalLayout.hbs |   25 +
 .../app/templates/modal/resultsDownload.hbs     |   42 +
 .../app/templates/partials/alert-content.hbs    |   25 +
 .../templates/partials/paginationControls.hbs   |   42 +
 .../resources/ui/pig-web/app/templates/pig.hbs  |   32 +-
 .../ui/pig-web/app/templates/pig/alert.hbs      |   21 +
 .../ui/pig-web/app/templates/pig/history.hbs    |   58 +-
 .../ui/pig-web/app/templates/pig/index.hbs      |   19 -
 .../ui/pig-web/app/templates/pig/job.hbs        |   39 -
 .../ui/pig-web/app/templates/pig/jobEdit.hbs    |   18 -
 .../ui/pig-web/app/templates/pig/jobResults.hbs |   19 -
 .../app/templates/pig/jobResultsOutput.hbs      |   40 -
 .../ui/pig-web/app/templates/pig/jobStatus.hbs  |   18 -
 .../app/templates/pig/modal/confirmdelete.hbs   |   29 -
 .../app/templates/pig/modal/createScript.hbs    |   40 -
 .../app/templates/pig/modal/createUdf.hbs       |   36 -
 .../app/templates/pig/modal/modalLayout.hbs     |   25 -
 .../ui/pig-web/app/templates/pig/scriptEdit.hbs |  167 ---
 .../app/templates/pig/scriptEditIndex.hbs       |   18 -
 .../ui/pig-web/app/templates/pig/scriptList.hbs |   62 -
 .../pig-web/app/templates/pig/scriptResults.hbs |   18 -
 .../app/templates/pig/scriptResultsNav.hbs      |   19 -
 .../ui/pig-web/app/templates/pig/scripts.hbs    |   86 ++
 .../ui/pig-web/app/templates/pig/udfs.hbs       |   24 +-
 .../app/templates/pig/util/alert-content.hbs    |   25 -
 .../ui/pig-web/app/templates/pig/util/alert.hbs |   21 -
 .../app/templates/pig/util/pigHelper.hbs        |   34 -
 .../app/templates/pig/util/script-nav.hbs       |   30 -
 .../ui/pig-web/app/templates/script.hbs         |   27 +
 .../ui/pig-web/app/templates/script/edit.hbs    |  146 +++
 .../ui/pig-web/app/templates/script/history.hbs |   61 +
 .../ui/pig-web/app/templates/script/job.hbs     |  153 +++
 .../ui/pig-web/app/templates/splash.hbs         |   66 +-
 .../resources/ui/pig-web/app/translations.js    |   67 +-
 .../main/resources/ui/pig-web/app/views/pig.js  |   49 +-
 .../resources/ui/pig-web/app/views/pig/alert.js |   55 +
 .../ui/pig-web/app/views/pig/history.js         |   46 +
 .../ui/pig-web/app/views/pig/jobResults.js      |   52 -
 .../ui/pig-web/app/views/pig/loading.js         |   23 +
 .../app/views/pig/modal/confirmDelete.js        |   29 -
 .../pig-web/app/views/pig/modal/createScript.js |   39 -
 .../ui/pig-web/app/views/pig/modal/createUdf.js |   38 -
 .../ui/pig-web/app/views/pig/modal/pigModal.js  |   35 -
 .../ui/pig-web/app/views/pig/pigHistory.js      |   36 -
 .../ui/pig-web/app/views/pig/pigJob.js          |   41 -
 .../ui/pig-web/app/views/pig/pigUdfs.js         |   23 -
 .../ui/pig-web/app/views/pig/scriptEdit.js      |  256 ----
 .../ui/pig-web/app/views/pig/scriptList.js      |   22 -
 .../ui/pig-web/app/views/pig/scriptResults.js   |   23 -
 .../pig-web/app/views/pig/scriptResultsNav.js   |   49 -
 .../ui/pig-web/app/views/pig/scripts.js         |   22 +
 .../resources/ui/pig-web/app/views/pig/udfs.js  |   23 +
 .../pig-web/app/views/pig/util/pigUtilAlert.js  |   55 -
 .../ui/pig-web/app/views/script/edit.js         |   56 +
 .../ui/pig-web/app/views/script/job.js          |   35 +
 .../src/main/resources/ui/pig-web/bower.json    |   26 +-
 .../src/main/resources/ui/pig-web/config.coffee |   27 +-
 .../src/main/resources/ui/pig-web/package.json  |    2 +-
 .../ui/pig-web/vendor/jquery-ui/core.js         |  304 +++++
 .../ui/pig-web/vendor/jquery-ui/draggable.js    | 1128 +++++++++++++++++
 .../ui/pig-web/vendor/jquery-ui/droppable.js    |  413 ++++++
 .../ui/pig-web/vendor/jquery-ui/mouse.js        |  199 +++
 .../ui/pig-web/vendor/jquery-ui/position.js     |  517 ++++++++
 .../ui/pig-web/vendor/jquery-ui/resizable.js    | 1179 ++++++++++++++++++
 .../ui/pig-web/vendor/jquery-ui/selectable.js   |  287 +++++
 .../ui/pig-web/vendor/jquery-ui/widget.js       |  557 +++++++++
 .../ui/pig-web/vendor/moment-duration-format.js |  482 +++++++
 contrib/views/pig/src/main/resources/view.xml   |   67 +-
 .../org/apache/ambari/view/pig/BasePigTest.java |   15 +-
 .../org/apache/ambari/view/pig/HDFSTest.java    |    3 +-
 .../apache/ambari/view/pig/test/FileTest.java   |    7 +-
 .../apache/ambari/view/pig/test/HelpTest.java   |    7 +-
 .../ambari/view/pig/test/IntegrationalTest.java |  134 ++
 .../apache/ambari/view/pig/test/JobTest.java    |  178 ++-
 .../apache/ambari/view/pig/test/ScriptTest.java |  273 ++--
 .../view/pig/test/ScriptTestHDFSUnmanaged.java  |   40 +-
 .../view/pig/test/ScriptTestUnmanaged.java      |    5 +-
 174 files changed, 10659 insertions(+), 3027 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pig/pom.xml b/contrib/views/pig/pom.xml
index 809cdd3..7aeab3a 100644
--- a/contrib/views/pig/pom.xml
+++ b/contrib/views/pig/pom.xml
@@ -169,7 +169,6 @@
               <arguments>
                 <argument>node_modules/.bin/brunch</argument>
                 <argument>build</argument>
-                <argument>--production</argument>
               </arguments>
             </configuration>
           </execution>

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/DataStoreStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/DataStoreStorage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/DataStoreStorage.java
new file mode 100644
index 0000000..d89e7a6
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/DataStoreStorage.java
@@ -0,0 +1,174 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence;
+
+import com.google.gson.Gson;
+import org.apache.ambari.view.PersistenceException;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.*;
+import org.apache.ambari.view.pig.utils.ServiceFormattedException;
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.WebApplicationException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Engine for storing objects to context DataStore storage
+ */
+public class DataStoreStorage implements Storage {
+  private final static Logger LOG =
+      LoggerFactory.getLogger(DataStoreStorage.class);
+  protected final Gson gson = new Gson();
+  protected ViewContext context;
+
+  /**
+   * Constructor
+   * @param context View Context instance
+   */
+  public DataStoreStorage(ViewContext context) {
+    this.context = context;
+  }
+
+  @Override
+  public synchronized void store(Indexed obj) {
+    try {
+      if (obj.getId() == null) {
+        int id = nextIdForEntity(context, obj.getClass());
+        obj.setId(String.valueOf(id));
+      }
+      context.getDataStore().store(obj);
+    } catch (PersistenceException e) {
+      throw new ServiceFormattedException("Error while saving object to DataStorage", e);
+    }
+  }
+
+  private static synchronized int nextIdForEntity(ViewContext context, Class aClass) {
+    // auto increment id implementation
+    String lastId = context.getInstanceData(aClass.getName());
+    int newId;
+    if (lastId == null) {
+      newId = 1;
+    } else {
+      newId = Integer.parseInt(lastId) + 1;
+    }
+    context.putInstanceData(aClass.getName(), String.valueOf(newId));
+    return newId;
+  }
+
+  @Override
+  public synchronized <T extends Indexed> T load(Class<T> model, int id) throws ItemNotFound {
+    LOG.debug(String.format("Loading %s #%d", model.getName(), id));
+    try {
+      T obj = context.getDataStore().find(model, String.valueOf(id));
+      if (obj != null) {
+        return obj;
+      } else {
+        throw new ItemNotFound();
+      }
+    } catch (PersistenceException e) {
+      throw new ServiceFormattedException("Error while finding object in DataStorage", e);
+    }
+  }
+
+  @Override
+  public synchronized <T extends Indexed> List<T> loadAll(Class<T> model, FilteringStrategy filter) {
+    LinkedList<T> list = new LinkedList<T>();
+    LOG.debug(String.format("Loading all %s-s", model.getName()));
+    try {
+      for(T item: context.getDataStore().findAll(model, null)) {
+        if ((filter == null) || filter.isConform(item)) {
+          list.add(item);
+        }
+      }
+    } catch (PersistenceException e) {
+      throw new ServiceFormattedException("Error while finding all objects in DataStorage", e);
+    }
+    return list;
+  }
+
+  @Override
+  public synchronized <T extends Indexed> List<T> loadAll(Class<T> model) {
+    return loadAll(model, new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+  }
+
+  @Override
+  public synchronized void delete(Class model, int id) throws ItemNotFound {
+    LOG.debug(String.format("Deleting %s:%d", model.getName(), id));
+    Object obj = load(model, id);
+    try {
+      context.getDataStore().remove(obj);
+    } catch (PersistenceException e) {
+      throw new ServiceFormattedException("Error while removing object from DataStorage", e);
+    }
+  }
+
+  @Override
+  public boolean exists(Class model, int id) {
+    try {
+      return context.getDataStore().find(model, String.valueOf(id)) != null;
+    } catch (PersistenceException e) {
+      throw new ServiceFormattedException("Error while finding object in DataStorage", e);
+    }
+  }
+
+  public static void storageSmokeTest(ViewContext context) {
+    try {
+      SmokeTestEntity entity = new SmokeTestEntity();
+      entity.setData("42");
+      DataStoreStorage storage = new DataStoreStorage(context);
+      storage.store(entity);
+
+      if (entity.getId() == null) throw new ServiceFormattedException("Ambari Views instance data DB doesn't work properly (auto increment id doesn't work)", null);
+      int id = Integer.parseInt(entity.getId());
+      SmokeTestEntity entity2 = storage.load(SmokeTestEntity.class, id);
+      boolean status = entity2.getData().compareTo("42") == 0;
+      storage.delete(SmokeTestEntity.class, id);
+      if (!status) throw new ServiceFormattedException("Ambari Views instance data DB doesn't work properly", null);
+    } catch (WebApplicationException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new ServiceFormattedException(ex.getMessage(), ex);
+    }
+  }
+
+  public static class SmokeTestEntity implements Indexed {
+    private String id = null;
+    private String data = null;
+
+    public String getId() {
+      return id;
+    }
+
+    public void setId(String id) {
+      this.id = id;
+    }
+
+    public String getData() {
+      return data;
+    }
+
+    public void setData(String data) {
+      this.data = data;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
index da1ca2f..de00a90 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
@@ -30,9 +30,9 @@ import javax.ws.rs.WebApplicationException;
 
 /**
  * Persistent storage engine for storing java beans to
- * properties file
- * Path to file should be in 'dataworker.storagePath' parameter
+ * instance data
  */
+@Deprecated
 public class InstanceKeyValueStorage extends KeyValueStorage {
   private final static Logger LOG =
       LoggerFactory.getLogger(InstanceKeyValueStorage.class);

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
index c3b87c2..44546c2 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
@@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
  * properties file
  * Path to file should be in 'dataworker.storagePath' parameter
  */
+@Deprecated
 public class LocalKeyValueStorage extends KeyValueStorage {
   private final static Logger LOG =
       LoggerFactory.getLogger(LocalKeyValueStorage.class);

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
index c3748c7..e5328cd 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
@@ -28,6 +28,7 @@ import java.io.File;
  * Configuration enables all necessary options for PropertiesConfiguration:
  * auto-save, auto-reloading, no delimiter parsing and other
  */
+@Deprecated
 public class PersistentConfiguration extends PropertiesConfiguration {
   /**
    * Constructor

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
index da9cfc3..e2c7db4 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
@@ -66,7 +66,7 @@ public interface Storage {
    * @param model bean class
    * @param id identifier
    */
-  void delete(Class model, int id);
+  void delete(Class model, int id) throws ItemNotFound;
 
   /**
    * Check is object exists

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
index d49a921..a281c39 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
@@ -25,11 +25,13 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 /**
  * Persistence API to Apache Configuration adapter
  */
+@Deprecated
 public class ContextConfigurationAdapter implements Configuration {
   private ViewContext context;
 
@@ -53,7 +55,8 @@ public class ContextConfigurationAdapter implements Configuration {
 
   @Override
   public boolean containsKey(String s) {
-    return context.getInstanceData().containsKey(s);
+    Map<String, String> data = context.getInstanceData();
+    return data.containsKey(s);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
index 245ad54..5d283f1 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
@@ -19,12 +19,16 @@
 package org.apache.ambari.view.pig.persistence.utils;
 
 import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.DataStoreStorage;
 import org.apache.ambari.view.pig.persistence.InstanceKeyValueStorage;
 import org.apache.ambari.view.pig.persistence.LocalKeyValueStorage;
 import org.apache.ambari.view.pig.persistence.Storage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Storage factory, creates storage of Local or Persistence API type.
  * Type depends on context configuration: if "dataworker.storagePath" is set,
@@ -33,17 +37,38 @@ import org.slf4j.LoggerFactory;
  * Storage is singleton.
  */
 public class StorageUtil {
-  private static Storage storageInstance = null;
+  private Storage storageInstance = null;
 
   protected final static Logger LOG =
       LoggerFactory.getLogger(StorageUtil.class);
 
+
+  private static Map<String, StorageUtil> viewSingletonObjects = new HashMap<String, StorageUtil>();
+  public static StorageUtil getInstance(ViewContext context) {
+    if (!viewSingletonObjects.containsKey(context.getInstanceName()))
+      viewSingletonObjects.put(context.getInstanceName(), new StorageUtil(context));
+    return viewSingletonObjects.get(context.getInstanceName());
+  }
+
+  public static void dropAllConnections() {
+    viewSingletonObjects.clear();
+  }
+
+  private ViewContext context;
+
   /**
-   * Get storage instance. If one is not created, creates instance.
+   * Constructor of storage util
    * @param context View Context instance
+   */
+  public StorageUtil(ViewContext context) {
+    this.context = context;
+  }
+
+  /**
+   * Get storage instance. If one is not created, creates instance.
    * @return storage instance
    */
-  public synchronized static Storage getStorage(ViewContext context) {
+  public synchronized Storage getStorage() {
     if (storageInstance == null) {
       String fileName = context.getProperties().get("dataworker.storagePath");
       if (fileName != null) {
@@ -53,7 +78,7 @@ public class StorageUtil {
       } else {
         LOG.debug("Using Persistence API to store data");
         // If not specifed, use ambari-views Persistence API
-        storageInstance = new InstanceKeyValueStorage(context);
+        storageInstance = new DataStoreStorage(context);
       }
     }
     return storageInstance;
@@ -64,7 +89,7 @@ public class StorageUtil {
    * Used in unit tests.
    * @param storage storage instance
    */
-  public static void setStorage(Storage storage) {
+  public void setStorage(Storage storage) {
     storageInstance = storage;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
index b4a2059..94c3b5a 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
@@ -113,7 +113,7 @@ abstract public class CRUDResourceManager<T extends Indexed> {
 
   protected Storage getPigStorage() {
     if (storage == null) {
-      storage = StorageUtil.getStorage(getContext());
+      storage = StorageUtil.getInstance(getContext()).getStorage();
     }
     return storage;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
index b54ca4b..1f6c2d9 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
@@ -55,7 +55,11 @@ public class PersonalCRUDResourceManager<T extends PersonalResource> extends CRU
 
   @Override
   public T save(T object) {
-    object.setOwner(this.context.getUsername());
+    if (!ignorePermissions) {
+      // in threads permissions should be ignored,
+      // because context.getUsername doesn't work. See BUG-27093.
+      object.setOwner(this.context.getUsername());
+    }
     return super.save(object);
   }
 
@@ -67,7 +71,7 @@ public class PersonalCRUDResourceManager<T extends PersonalResource> extends CRU
   }
 
   @Override
-  protected ViewContext getContext() {
+  public ViewContext getContext() {
     return context;
   }
 
@@ -88,10 +92,14 @@ public class PersonalCRUDResourceManager<T extends PersonalResource> extends CRU
     return result;
   }
 
-  protected String getUsername() {
+  protected static String getUsername(ViewContext context) {
     String userName = context.getProperties().get("dataworker.username");
-    if (userName == null)
+    if (userName == null || userName.compareTo("null") == 0 || userName.compareTo("") == 0)
       userName = context.getUsername();
     return userName;
   }
+
+  protected String getUsername() {
+    return getUsername(context);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
index 155c6d9..aaf877c 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
@@ -164,7 +164,7 @@ public class FileService extends BaseService {
    */
   public static void hdfsSmokeTest(ViewContext context) {
     try {
-      HdfsApi api = connectToHDFSApi(context);
+      HdfsApi api = HdfsApi.connectToHDFSApi(context);
       api.getStatus();
     } catch (WebApplicationException ex) {
       throw ex;

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
index a43a992..0230625 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
@@ -26,6 +26,7 @@ import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
 import org.apache.ambari.view.pig.resources.jobs.utils.JobPolling;
 import org.apache.ambari.view.pig.services.BaseService;
 import org.apache.ambari.view.pig.templeton.client.TempletonApi;
+import org.apache.ambari.view.pig.utils.HdfsApi;
 import org.apache.ambari.view.pig.utils.MisconfigurationFormattedException;
 import org.apache.ambari.view.pig.utils.ServiceFormattedException;
 import org.apache.hadoop.fs.FSDataOutputStream;
@@ -89,26 +90,26 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
     });
 
     for(PigJob job : notCompleted) {
-      JobPolling.pollJob(context, job);
+      JobPolling.pollJob(this, job);
     }
   }
 
   @Override
   public PigJob create(PigJob object) {
-    object.setStatus(PigJob.Status.SUBMITTING);
+    object.setStatus(PigJob.PIG_JOB_STATE_SUBMITTING);
     PigJob job = super.create(object);
     LOG.debug("Submitting job...");
 
     try {
       submitJob(object);
     } catch (RuntimeException e) {
-      object.setStatus(PigJob.Status.SUBMIT_FAILED);
+      object.setStatus(PigJob.PIG_JOB_STATE_SUBMIT_FAILED);
       save(object);
       LOG.debug("Job submit FAILED");
       throw e;
     }
     LOG.debug("Job submit OK");
-    object.setStatus(PigJob.Status.SUBMITTED);
+    object.setStatus(PigJob.PIG_JOB_STATE_SUBMITTED);
     save(object);
     return job;
   }
@@ -121,13 +122,17 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
   public void killJob(PigJob object) throws IOException {
     LOG.debug("Killing job...");
 
-    try {
-      getTempletonApi().killJob(object.getJobId());
-    } catch (IOException e) {
-      LOG.debug("Job kill FAILED");
-      throw e;
+    if (object.getJobId() != null) {
+      try {
+        getTempletonApi().killJob(object.getJobId());
+      } catch (IOException e) {
+        LOG.debug("Job kill FAILED");
+        throw e;
+      }
+      LOG.debug("Job kill OK");
+    } else {
+      LOG.debug("Job was not submitted, ignoring kill request...");
     }
-    LOG.debug("Job kill OK");
   }
 
   /**
@@ -136,15 +141,18 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
    */
   private void submitJob(PigJob job) {
     String date = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss").format(new Date());
-    String statusdir = String.format(context.getProperties().get("dataworker.jobs.path") +
-            "/%s/%s_%s", getUsername(),
-        job.getTitle().toLowerCase().replaceAll("[^a-zA-Z0-9 ]+", "").replace(" ", "_"),
-        date);
+    String jobsBaseDir = context.getProperties().get("jobs.dir");
+    String storeBaseDir = context.getProperties().get("store.dir");
+    if (storeBaseDir == null || storeBaseDir.compareTo("null") == 0 || storeBaseDir.compareTo("") == 0)
+      storeBaseDir = context.getProperties().get("jobs.dir");
+    String jobNameCleaned = job.getTitle().toLowerCase().replaceAll("[^a-zA-Z0-9 ]+", "").replace(" ", "_");
+    String storedir = String.format(storeBaseDir + "/%s_%s", jobNameCleaned, date);
+    String statusdir = String.format(jobsBaseDir + "/%s_%s", jobNameCleaned, date);
 
-    String newPigScriptPath = statusdir + "/script.pig";
-    String newSourceFilePath = statusdir + "/source.pig";
-    String newPythonScriptPath = statusdir + "/udf.py";
-    String templetonParamsFilePath = statusdir + "/params";
+    String newPigScriptPath = storedir + "/script.pig";
+    String newSourceFilePath = storedir + "/source.pig";
+    String newPythonScriptPath = storedir + "/udf.py";
+    String templetonParamsFilePath = storedir + "/params";
     try {
       // additional file can be passed to copy into work directory
       if (job.getSourceFileContent() != null && !job.getSourceFileContent().isEmpty()) {
@@ -152,13 +160,13 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
         job.setSourceFileContent(null); // we should not store content in DB
         save(job);
 
-        FSDataOutputStream stream = BaseService.getHdfsApi(context).create(newSourceFilePath, true);
+        FSDataOutputStream stream = HdfsApi.getInstance(context).create(newSourceFilePath, true);
         stream.writeBytes(sourceFileContent);
         stream.close();
       } else {
         if (job.getSourceFile() != null && !job.getSourceFile().isEmpty()) {
           // otherwise, just copy original file
-          if (!BaseService.getHdfsApi(context).copy(job.getSourceFile(), newSourceFilePath)) {
+          if (!HdfsApi.getInstance(context).copy(job.getSourceFile(), newSourceFilePath)) {
             throw new ServiceFormattedException("Can't copy source file from " + job.getSourceFile() +
                 " to " + newPigScriptPath);
           }
@@ -176,16 +184,16 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
         String forcedContent = job.getForcedContent();
         // variable for sourceFile can be passed from front-ent
         forcedContent = forcedContent.replace("${sourceFile}",
-            context.getProperties().get("dataworker.defaultFs") + newSourceFilePath);
+            context.getProperties().get("webhdfs.url") + newSourceFilePath);
         job.setForcedContent(null); // we should not store content in DB
         save(job);
 
-        FSDataOutputStream stream = BaseService.getHdfsApi(context).create(newPigScriptPath, true);
+        FSDataOutputStream stream = HdfsApi.getInstance(context).create(newPigScriptPath, true);
         stream.writeBytes(forcedContent);
         stream.close();
       } else {
         // otherwise, just copy original file
-        if (!BaseService.getHdfsApi(context).copy(job.getPigScript(), newPigScriptPath)) {
+        if (!HdfsApi.getInstance(context).copy(job.getPigScript(), newPigScriptPath)) {
           throw new ServiceFormattedException("Can't copy pig script file from " + job.getPigScript() +
               " to " + newPigScriptPath);
         }
@@ -198,7 +206,7 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
 
     if (job.getPythonScript() != null && !job.getPythonScript().isEmpty()) {
       try {
-        if (!BaseService.getHdfsApi(context).copy(job.getPythonScript(), newPythonScriptPath)) {
+        if (!HdfsApi.getInstance(context).copy(job.getPythonScript(), newPythonScriptPath)) {
           throw new ServiceFormattedException("Can't copy python udf script file from " + job.getPythonScript() +
               " to " + newPythonScriptPath);
         }
@@ -210,7 +218,7 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
     }
 
     try {
-      FSDataOutputStream stream = BaseService.getHdfsApi(context).create(templetonParamsFilePath, true);
+      FSDataOutputStream stream = HdfsApi.getInstance(context).create(templetonParamsFilePath, true);
       if (job.getTempletonArguments() != null) {
         stream.writeBytes(job.getTempletonArguments());
       }
@@ -235,7 +243,7 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
     }
     job.setJobId(data.id);
 
-    JobPolling.pollJob(context, job);
+    JobPolling.pollJob(this, job);
   }
 
   /**
@@ -253,29 +261,40 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
 
     if (info.status != null && (info.status.containsKey("runState"))) {
       //TODO: retrieve from RM
+      Long time = System.currentTimeMillis() / 1000L;
+      Long currentDuration = time - job.getDateStarted();
       int runState = ((Double) info.status.get("runState")).intValue();
+      boolean isStatusChanged = false;
       switch (runState) {
-        case PigJob.RUN_STATE_KILLED:
+        case RUN_STATE_KILLED:
           LOG.debug(String.format("Job KILLED: %s", job.getJobId()));
-          job.setStatus(PigJob.Status.KILLED);
+          isStatusChanged = job.getStatus() != PigJob.PIG_JOB_STATE_KILLED;
+          job.setStatus(PigJob.PIG_JOB_STATE_KILLED);
           break;
-        case PigJob.RUN_STATE_FAILED:
+        case RUN_STATE_FAILED:
           LOG.debug(String.format("Job FAILED: %s", job.getJobId()));
-          job.setStatus(PigJob.Status.FAILED);
+          isStatusChanged = job.getStatus() != PigJob.PIG_JOB_STATE_FAILED;
+          job.setStatus(PigJob.PIG_JOB_STATE_FAILED);
           break;
-        case PigJob.RUN_STATE_PREP:
-        case PigJob.RUN_STATE_RUNNING:
-          job.setStatus(PigJob.Status.RUNNING);
+        case RUN_STATE_PREP:
+        case RUN_STATE_RUNNING:
+          isStatusChanged = job.getStatus() != PigJob.PIG_JOB_STATE_RUNNING;
+          job.setStatus(PigJob.PIG_JOB_STATE_RUNNING);
           break;
-        case PigJob.RUN_STATE_SUCCEEDED:
+        case RUN_STATE_SUCCEEDED:
           LOG.debug(String.format("Job COMPLETED: %s", job.getJobId()));
-          job.setStatus(PigJob.Status.COMPLETED);
+          isStatusChanged = job.getStatus() != PigJob.PIG_JOB_STATE_COMPLETED;
+          job.setStatus(PigJob.PIG_JOB_STATE_COMPLETED);
           break;
         default:
           LOG.debug(String.format("Job in unknown state: %s", job.getJobId()));
-          job.setStatus(PigJob.Status.UNKNOWN);
+          isStatusChanged = job.getStatus() != PigJob.PIG_JOB_STATE_UNKNOWN;
+          job.setStatus(PigJob.PIG_JOB_STATE_UNKNOWN);
           break;
       }
+      if (isStatusChanged) {
+        job.setDuration(currentDuration);
+      }
     }
     Pattern pattern = Pattern.compile("\\d+");
     Matcher matcher = null;
@@ -306,13 +325,13 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
   }
 
   private static TempletonApi connectToTempletonApi(ViewContext context) {
-    String webhcatUrl = context.getProperties().get("dataworker.webhcat.url");
+    String webhcatUrl = context.getProperties().get("webhcat.url");
     if (webhcatUrl == null) {
-      String message = "dataworker.webhcat.url is not configured!";
+      String message = "webhcat.url is not configured!";
       LOG.error(message);
-      throw new MisconfigurationFormattedException("dataworker.webhcat.url");
+      throw new MisconfigurationFormattedException("webhcat.url");
     }
-    return new TempletonApi(context.getProperties().get("dataworker.webhcat.url"),
+    return new TempletonApi(context.getProperties().get("webhcat.url"),
         getTempletonUser(context), getTempletonUser(context), context);
   }
 
@@ -322,12 +341,16 @@ public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
    * @return username in templeton
    */
   private static String getTempletonUser(ViewContext context) {
-    String username = context.getProperties().get("dataworker.webhcat.user");
-    if (username == null) {
-      String message = "dataworker.webhcat.user is not configured!";
-      LOG.error(message);
-      throw new MisconfigurationFormattedException("dataworker.webhcat.user");
+    String username = context.getProperties().get("webhcat.username");
+    if (username == null || username.compareTo("null") == 0 || username.compareTo("") == 0) {
+      username = getUsername(context);
     }
     return username;
   }
+
+  public static final int RUN_STATE_RUNNING = 1;
+  public static final int RUN_STATE_SUCCEEDED = 2;
+  public static final int RUN_STATE_FAILED = 3;
+  public static final int RUN_STATE_PREP = 4;
+  public static final int RUN_STATE_KILLED = 5;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
index c4f2d29..9ecbd75 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
@@ -21,6 +21,7 @@ package org.apache.ambari.view.pig.resources.jobs;
 import com.google.inject.Inject;
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
 import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
 import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
 import org.apache.ambari.view.pig.resources.files.FileResource;
@@ -31,6 +32,8 @@ import org.apache.ambari.view.pig.utils.FilePaginator;
 import org.apache.ambari.view.pig.utils.NotFoundFormattedException;
 import org.apache.ambari.view.pig.utils.ServiceFormattedException;
 import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.*;
@@ -57,6 +60,9 @@ public class JobService extends BaseService {
   @Inject
   ViewResourceHandler handler;
 
+  protected final static Logger LOG =
+      LoggerFactory.getLogger(JobService.class);
+
   protected JobResourceManager resourceManager = null;
 
   /**
@@ -108,7 +114,8 @@ public class JobService extends BaseService {
    */
   @DELETE
   @Path("{jobId}")
-  public Response killJob(@PathParam("jobId") String jobId) throws IOException {
+  public Response killJob(@PathParam("jobId") String jobId,
+                          @QueryParam("remove") final String remove) throws IOException {
     try {
       PigJob job = null;
       try {
@@ -117,6 +124,9 @@ public class JobService extends BaseService {
         throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
       }
       getResourceManager().killJob(job);
+      if (remove != null && remove.compareTo("true") == 0) {
+        getResourceManager().delete(jobId);
+      }
       return Response.status(204).build();
     } catch (WebApplicationException ex) {
       throw ex;
@@ -206,10 +216,20 @@ public class JobService extends BaseService {
    */
   @GET
   @Produces(MediaType.APPLICATION_JSON)
-  public Response getJobList(@Context HttpHeaders headers, @Context UriInfo ui) {
+  public Response getJobList(@QueryParam("scriptId") final String scriptId) {
     try {
       List allJobs = getResourceManager().readAll(
-          new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+          new OnlyOwnersFilteringStrategy(this.context.getUsername()) {
+            @Override
+            public boolean isConform(Indexed item) {
+              if (scriptId == null)
+                return super.isConform(item);
+              else {
+                PigJob job = (PigJob) item;
+                return (job.getScriptId() != null && scriptId.compareTo(job.getScriptId()) == 0 && super.isConform(item));
+              }
+            }
+          });  //TODO: move strategy to PersonalCRUDRM
 
       JSONObject object = new JSONObject();
       object.put("jobs", allJobs);

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
index f55da93..6f80d6b 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
@@ -20,7 +20,6 @@ package org.apache.ambari.view.pig.resources.jobs.models;
 
 import org.apache.ambari.view.pig.persistence.utils.PersonalResource;
 import org.apache.commons.beanutils.BeanUtils;
-import org.codehaus.jackson.annotate.JsonIgnore;
 
 import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
@@ -42,23 +41,16 @@ import java.util.Map;
  * COMPLETED      KILLED        FAILED
  */
 public class PigJob implements Serializable, PersonalResource {
-
-  public enum Status {
-    UNKNOWN,
-    SUBMITTING, SUBMITTED, RUNNING,  // in progress
-    SUBMIT_FAILED, COMPLETED, FAILED, KILLED  // finished
-  }
-
-  public boolean isInProgress() {
-    return status == Status.SUBMITTED || status == Status.SUBMITTING ||
-        status == Status.RUNNING;
-  }
-
-  public static final int RUN_STATE_RUNNING = 1;
-  public static final int RUN_STATE_SUCCEEDED = 2;
-  public static final int RUN_STATE_FAILED = 3;
-  public static final int RUN_STATE_PREP = 4;
-  public static final int RUN_STATE_KILLED = 5;
+  public static final String PIG_JOB_STATE_UNKNOWN = "UNKNOWN";
+  // in progress
+  public static final String PIG_JOB_STATE_SUBMITTING = "SUBMITTING";
+  public static final String PIG_JOB_STATE_SUBMITTED = "SUBMITTED";
+  public static final String PIG_JOB_STATE_RUNNING = "RUNNING";
+  // finished
+  public static final String PIG_JOB_STATE_SUBMIT_FAILED = "SUBMIT_FAILED";
+  public static final String PIG_JOB_STATE_COMPLETED = "COMPLETED";
+  public static final String PIG_JOB_STATE_FAILED = "FAILED";
+  public static final String PIG_JOB_STATE_KILLED = "KILLED";
 
   public PigJob() {
   }
@@ -96,10 +88,11 @@ public class PigJob implements Serializable, PersonalResource {
 
   private String statusDir;
   private Long dateStarted = 0L;
+  private Long duration = 0L;
   private String jobId = null;
 
   // status fields (not reliable)
-  private Status status = Status.UNKNOWN;
+  private String status = PIG_JOB_STATE_UNKNOWN;
   private Integer percentComplete = null;
 
   @Override
@@ -119,6 +112,11 @@ public class PigJob implements Serializable, PersonalResource {
     return id.hashCode();
   }
 
+  public boolean isInProgress() {
+    return status.equals(PIG_JOB_STATE_SUBMITTED) || status.equals(PIG_JOB_STATE_SUBMITTING) ||
+        status.equals(PIG_JOB_STATE_RUNNING);
+  }
+
   @Override
   public String getId() {
     return id;
@@ -139,11 +137,11 @@ public class PigJob implements Serializable, PersonalResource {
     this.owner = owner;
   }
 
-  public Status getStatus() {
+  public String getStatus() {
     return status;
   }
 
-  public void setStatus(Status status) {
+  public void setStatus(String status) {
     this.status = status;
   }
 
@@ -203,6 +201,14 @@ public class PigJob implements Serializable, PersonalResource {
     this.dateStarted = dateStarted;
   }
 
+  public Long getDuration() {
+    return duration;
+  }
+
+  public void setDuration(Long duration) {
+    this.duration = duration;
+  }
+
   public Integer getPercentComplete() {
     return percentComplete;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
index bc633b2..8a60a1c 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
@@ -18,7 +18,8 @@
 
 package org.apache.ambari.view.pig.resources.jobs.utils;
 
-import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.FilteringStrategy;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
 import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
 import org.apache.ambari.view.pig.resources.jobs.JobResourceManager;
 import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
@@ -26,12 +27,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
-import java.util.Observable;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.*;
 
 /**
  * Polling manager
@@ -49,67 +47,71 @@ public class JobPolling implements Runnable {
    */
   private static final int WORKER_COUNT = 2;
 
-  private static final int POLLING_DELAY = 10*60;  // 10 minutes
+  private static final int POLLING_DELAY = 60;  // 1 minutes
 
   /**
    * In LONG_JOB_THRESHOLD seconds job reschedules polling from POLLING_DELAY to LONG_POLLING_DELAY
    */
-  private static final int LONG_POLLING_DELAY = 60*60; // 1 hour
-  private static final int LONG_JOB_THRESHOLD = 60*60; // 1 hour
+  private static final int LONG_POLLING_DELAY = 10*60; // 10 minutes
+  private static final int LONG_JOB_THRESHOLD = 10*60; // 10 minutes
 
   private static final ScheduledExecutorService pollWorkersPool = Executors.newScheduledThreadPool(WORKER_COUNT);
 
   private static final Map<String, JobPolling> jobPollers = new HashMap<String, JobPolling>();
 
   private JobResourceManager resourceManager = null;
-  private final ViewContext context;
   private PigJob job;
   private volatile ScheduledFuture<?> thisFuture;
 
-  private JobPolling(ViewContext context, PigJob job) {
-    this.context = context;
+  private JobPolling(JobResourceManager resourceManager, PigJob job) {
+    this.resourceManager = resourceManager;
     this.job = job;
   }
 
-  protected synchronized JobResourceManager getResourceManager() {
-    if (resourceManager == null) {
-      resourceManager = new JobResourceManager(context);
-    }
-    return resourceManager;
-  }
-
   /**
    * Do polling
    */
   public void run() {
-    LOG.debug("Polling job status " + job.getJobId() + " #" + job.getId());
     try {
-      job = getResourceManager().read(job.getId());
-    } catch (ItemNotFound itemNotFound) {
-      LOG.error("Job " + job.getJobId() + " does not exist! Polling canceled");
-      thisFuture.cancel(false);
-      return;
-    }
-    getResourceManager().retrieveJobStatus(job);
-
-    Long time = System.currentTimeMillis() / 1000L;
-    if (time - job.getDateStarted() > LONG_JOB_THRESHOLD) {
-      LOG.debug("Job becomes long.. Rescheduling polling to longer period");
-      // If job running longer than LONG_JOB_THRESHOLD, reschedule
-      // it to poll every LONG_POLLING_DELAY instead of POLLING_DELAY
-      thisFuture.cancel(false);
-      scheduleJobPolling(true);
-    }
-
-    switch (job.getStatus()) {
-      case SUBMIT_FAILED:
-      case COMPLETED:
-      case FAILED:
-      case KILLED:
-        LOG.debug("Job finished. Polling canceled");
-        thisFuture.cancel(false);
-        break;
-      default:
+      // Hack to make permission check work. It is based on
+      // context.getUsername(), but it doesn't work in another thread. See BUG-27093.
+      resourceManager.ignorePermissions(new Callable<Void>() {
+        @Override
+        public Void call() throws Exception {
+          LOG.debug("Polling job status " + job.getJobId() + " #" + job.getId());
+          try {
+            job = resourceManager.read(job.getId());
+          } catch (ItemNotFound itemNotFound) {
+            LOG.error("Job " + job.getId() + " does not exist! Polling canceled");
+            thisFuture.cancel(false);
+            return null;
+          }
+          resourceManager.retrieveJobStatus(job);
+
+          Long time = System.currentTimeMillis() / 1000L;
+          if (time - job.getDateStarted() > LONG_JOB_THRESHOLD) {
+            LOG.debug("Job becomes long.. Rescheduling polling to longer period");
+            // If job running longer than LONG_JOB_THRESHOLD, reschedule
+            // it to poll every LONG_POLLING_DELAY instead of POLLING_DELAY
+            thisFuture.cancel(false);
+            scheduleJobPolling(true);
+          }
+
+          if (job.getStatus().equals(PigJob.PIG_JOB_STATE_SUBMIT_FAILED) ||
+              job.getStatus().equals(PigJob.PIG_JOB_STATE_COMPLETED) ||
+              job.getStatus().equals(PigJob.PIG_JOB_STATE_FAILED) ||
+              job.getStatus().equals(PigJob.PIG_JOB_STATE_KILLED)) {
+            LOG.debug("Job finished. Polling canceled");
+            thisFuture.cancel(false);
+
+          } else {
+          }
+          return null;
+        }
+      });
+    } catch (Exception e) {
+      LOG.error("Exception during handling job polling: " + e.getMessage());
+      e.printStackTrace();
     }
   }
 
@@ -129,14 +131,13 @@ public class JobPolling implements Runnable {
 
   /**
    * Schedule job polling
-   * @param context ViewContext of web app
    * @param job job instance
    * @return returns false if already scheduled
    */
-  public static boolean pollJob(ViewContext context, PigJob job) {
+  public static boolean pollJob(JobResourceManager resourceManager, PigJob job) {
     if (jobPollers.get(job.getJobId()) == null) {
       LOG.debug("Setting up polling for " + job.getJobId());
-      JobPolling polling = new JobPolling(context, job);
+      JobPolling polling = new JobPolling(resourceManager, job);
       polling.scheduleJobPolling();
       jobPollers.put(job.getJobId(), polling);
       return true;

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
index c213a6e..9a56bb4 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
@@ -23,6 +23,7 @@ import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
 import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
 import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
 import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.ambari.view.pig.utils.HdfsApi;
 import org.apache.ambari.view.pig.utils.MisconfigurationFormattedException;
 import org.apache.ambari.view.pig.utils.ServiceFormattedException;
 import org.apache.hadoop.fs.FSDataOutputStream;
@@ -59,11 +60,11 @@ public class ScriptResourceManager extends PersonalCRUDResourceManager<PigScript
   }
 
   private void createDefaultScriptFile(PigScript object) {
-    String userScriptsPath = context.getProperties().get("dataworker.scripts.path");
+    String userScriptsPath = context.getProperties().get("scripts.dir");
     if (userScriptsPath == null) {
-      String msg = "dataworker.scripts.path is not configured!";
+      String msg = "scripts.dir is not configured!";
       LOG.error(msg);
-      throw new MisconfigurationFormattedException("dataworker.scripts.path");
+      throw new MisconfigurationFormattedException("scripts.dir");
     }
     int checkId = 0;
 
@@ -73,12 +74,11 @@ public class ScriptResourceManager extends PersonalCRUDResourceManager<PigScript
       String normalizedName = object.getTitle().replaceAll("[^a-zA-Z0-9 ]+", "").replaceAll(" ", "_").toLowerCase();
       String timestamp = new SimpleDateFormat("yyyy-MM-dd_hh-mm").format(new Date());
       newFilePath = String.format(userScriptsPath +
-              "/%s/%s-%s%s.pig", getUsername(),
-          normalizedName, timestamp, (checkId == 0)?"":"_"+checkId);
+              "/%s-%s%s.pig", normalizedName, timestamp, (checkId == 0)?"":"_"+checkId);
       LOG.debug("Trying to create new file " + newFilePath);
 
       try {
-        FSDataOutputStream stream = BaseService.getHdfsApi(context).create(newFilePath, false);
+        FSDataOutputStream stream = HdfsApi.getInstance(context).create(newFilePath, false);
         stream.close();
         fileCreated = true;
         LOG.debug("File created successfully!");

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
index 0e7536e..46e6247 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
@@ -111,7 +111,7 @@ public class ScriptService extends BaseService {
     try {
       LOG.debug("Getting all scripts");
       List allScripts = getResourceManager().readAll(
-          new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+          new OnlyOwnersFilteringStrategy(this.context.getUsername()));  //TODO: move strategy to PersonalCRUDRM
 
       JSONObject object = new JSONObject();
       object.put("scripts", allScripts);

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
index 741e32f..ec15c37 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
@@ -42,14 +42,14 @@ public class BaseService {
   @Inject
   protected ViewContext context;
 
-  protected final static Logger LOG =
+  private final static Logger LOG =
       LoggerFactory.getLogger(BaseService.class);
 
   private Storage storage;
 
   protected Storage getStorage() {
     if (this.storage == null) {
-      storage = StorageUtil.getStorage(context);
+      storage = StorageUtil.getInstance(context).getStorage();
     }
     return storage;
   }
@@ -58,62 +58,19 @@ public class BaseService {
     this.storage = storage;
   }
 
-  private static HdfsApi hdfsApi = null;
-
-  /**
-   * Returns HdfsApi object
-   * @param context View Context instance
-   * @return Hdfs business delegate object
-   */
-  public static HdfsApi getHdfsApi(ViewContext context) {
-    if (hdfsApi == null) {
-      hdfsApi = connectToHDFSApi(context);
-    }
-    return hdfsApi;
-  }
-
-  protected static HdfsApi connectToHDFSApi(ViewContext context) {
-    HdfsApi api = null;
-    Thread.currentThread().setContextClassLoader(null);
-
-    String defaultFS = context.getProperties().get("dataworker.defaultFs");
-    if (defaultFS == null) {
-      String message = "dataworker.defaultFs is not configured!";
-      LOG.error(message);
-      throw new MisconfigurationFormattedException("dataworker.defaultFs");
-    }
-
-    try {
-      api = new HdfsApi(defaultFS, getHdfsUsername(context));
-      LOG.info("HdfsApi connected OK");
-    } catch (IOException e) {
-      String message = "HdfsApi IO error: " + e.getMessage();
-      LOG.error(message);
-      throw new ServiceFormattedException(message, e);
-    } catch (InterruptedException e) {
-      String message = "HdfsApi Interrupted error: " + e.getMessage();
-      LOG.error(message);
-      throw new ServiceFormattedException(message, e);
-    }
-    return api;
-  }
-
-  public static String getHdfsUsername(ViewContext context) {
-    String userName = context.getProperties().get("dataworker.hdfs.username");
-    if (userName == null)
-      userName = context.getUsername();
-    return userName;
-  }
+  private HdfsApi hdfsApi = null;
 
   protected HdfsApi getHdfsApi()  {
-    return getHdfsApi(context);
+    if (hdfsApi == null)
+      hdfsApi = HdfsApi.getInstance(context);
+    return hdfsApi;
   }
 
   /**
    * Set HdfsApi delegate
    * @param api HdfsApi instance
    */
-  public static void setHdfsApi(HdfsApi api)  {
+  public void setHdfsApi(HdfsApi api)  {
     hdfsApi = api;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
index 1a0e6dd..eb363a0 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
@@ -20,6 +20,7 @@ package org.apache.ambari.view.pig.services;
 
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.DataStoreStorage;
 import org.apache.ambari.view.pig.persistence.InstanceKeyValueStorage;
 import org.apache.ambari.view.pig.resources.files.FileService;
 import org.apache.ambari.view.pig.resources.jobs.JobResourceManager;
@@ -59,8 +60,8 @@ public class HelpService extends BaseService {
   @Produces(MediaType.APPLICATION_JSON)
   public Response config(){
     JSONObject object = new JSONObject();
-    String fs = context.getProperties().get("dataworker.defaultFs");
-    object.put("dataworker.defaultFs", fs);
+    String fs = context.getProperties().get("webhdfs.url");
+    object.put("webhdfs.url", fs);
     return Response.ok(object).build();
   }
 
@@ -111,7 +112,7 @@ public class HelpService extends BaseService {
   @Path("/storageStatus")
   @Produces(MediaType.APPLICATION_JSON)
   public Response storageStatus(){
-    InstanceKeyValueStorage.storageSmokeTest(context);
+    DataStoreStorage.storageSmokeTest(context);
     return getOKResponse();
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
index a23f008..521bfad 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
@@ -69,6 +69,7 @@ public class Request<RESPONSE> {
     InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(), "GET",
         null, new HashMap<String, String>());
 
+    LOG.info(String.format("curl \"" + resource.toString() + "\""));
     String responseJson = IOUtils.toString(inputStream);
     LOG.debug(String.format("RESPONSE => %s", responseJson));
     return gson.fromJson(responseJson, responseClass);
@@ -100,10 +101,14 @@ public class Request<RESPONSE> {
     LOG.debug("POST " + resource.toString());
     LOG.debug("data: " + data.toString());
 
+    StringBuilder curlBuilder = new StringBuilder();
+
     UriBuilder builder = UriBuilder.fromPath("host/");
     for(String key : data.keySet()) {
-      for(String value : data.get(key))
+      for(String value : data.get(key)) {
         builder.queryParam(key, value);
+        curlBuilder.append(String.format("-d %s=\"%s\"", key, value.replace("\"", "\\\"")));
+      }
     }
 
     if (data != null)
@@ -112,6 +117,7 @@ public class Request<RESPONSE> {
     Map<String, String> headers = new HashMap<String, String>();
     headers.put("Content-Type", "application/x-www-form-urlencoded");
 
+    LOG.info(String.format("curl " + curlBuilder.toString() + " \"" + resource.toString() + "\""));
     InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(),
         "POST", builder.build().getRawQuery(), headers);
     String responseJson = IOUtils.toString(inputStream);
@@ -150,10 +156,14 @@ public class Request<RESPONSE> {
   public RESPONSE put(WebResource resource, MultivaluedMapImpl data) throws IOException {
     LOG.debug("PUT " + resource.toString());
 
+    StringBuilder curlBuilder = new StringBuilder();
+
     UriBuilder builder = UriBuilder.fromPath("host/");
     for(String key : data.keySet()) {
-      for(String value : data.get(key))
+      for(String value : data.get(key)) {
         builder.queryParam(key, value);
+        curlBuilder.append(String.format("-d %s=\"%s\"", key, value.replace("\"", "\\\"")));
+      }
     }
 
     if (data != null)
@@ -162,6 +172,8 @@ public class Request<RESPONSE> {
     Map<String, String> headers = new HashMap<String, String>();
     headers.put("Content-Type", "application/x-www-form-urlencoded");
 
+    LOG.info(String.format("curl -X PUT " + curlBuilder.toString() + " \"" + resource.toString() + "\""));
+
     InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(),
         "PUT", builder.build().getRawQuery(), headers);
     String responseJson = IOUtils.toString(inputStream);
@@ -200,10 +212,14 @@ public class Request<RESPONSE> {
   public RESPONSE delete(WebResource resource, MultivaluedMapImpl data) throws IOException {
     LOG.debug("DELETE " + resource.toString());
 
+    StringBuilder curlBuilder = new StringBuilder();
+
     UriBuilder builder = UriBuilder.fromPath("host/");
     for(String key : data.keySet()) {
-      for(String value : data.get(key))
+      for(String value : data.get(key)) {
         builder.queryParam(key, value);
+        curlBuilder.append(String.format("-d %s=\"%s\"", key, value.replace("\"", "\\\"")));
+      }
     }
 
     if (data != null)
@@ -212,6 +228,8 @@ public class Request<RESPONSE> {
     Map<String, String> headers = new HashMap<String, String>();
     headers.put("Content-Type", "application/x-www-form-urlencoded");
 
+    LOG.info(String.format("curl -X DELETE " + curlBuilder.toString() + " \"" + resource.toString() + "\""));
+
     InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(),
         "DELETE", builder.build().getRawQuery(), headers);
     String responseJson = IOUtils.toString(inputStream);

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
index 9ad54ac..d45b55c 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
@@ -52,7 +52,7 @@ public class TempletonApi {
 
   /**
    * TempletonApi constructor
-   * @param api dataworker.webhcat.url
+   * @param api webhcat.url
    * @param username templeton username
    * @param doAs doAs argument
    * @param context context with URLStreamProvider

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
index 2d49c97..9ebbb80 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
@@ -44,7 +44,7 @@ public class FilePaginator {
    */
   public FilePaginator(String filePath, ViewContext context) {
     this.filePath = filePath;
-    hdfsApi = BaseService.getHdfsApi(context);
+    hdfsApi = HdfsApi.getInstance(context);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
index 845b459..f9dfb35 100644
--- a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
@@ -18,6 +18,7 @@
 
 package org.apache.ambari.view.pig.utils;
 
+import org.apache.ambari.view.ViewContext;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.*;
 import org.apache.hadoop.fs.permission.FsPermission;
@@ -29,10 +30,13 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.URI;
 import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.hadoop.security.UserGroupInformation;
 import org.json.simple.JSONArray;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.LinkedHashMap;
 
@@ -45,6 +49,9 @@ public class HdfsApi {
   private FileSystem fs;
   private UserGroupInformation ugi;
 
+  private final static Logger LOG =
+      LoggerFactory.getLogger(HdfsApi.class);
+
   /**
    * Constructor
    * @param defaultFs hdfs uri
@@ -284,4 +291,57 @@ public class HdfsApi {
     return json;
   }
 
+
+  private static Map<String, HdfsApi> viewSingletonObjects = new HashMap<String, HdfsApi>();
+  /**
+   * Returns HdfsApi object specific to instance
+   * @param context View Context instance
+   * @return Hdfs business delegate object
+   */
+  public static HdfsApi getInstance(ViewContext context) {
+    if (!viewSingletonObjects.containsKey(context.getInstanceName()))
+      viewSingletonObjects.put(context.getInstanceName(), connectToHDFSApi(context));
+    return viewSingletonObjects.get(context.getInstanceName());
+  }
+
+  public static void setInstance(ViewContext context, HdfsApi api) {
+    viewSingletonObjects.put(context.getInstanceName(), api);
+  }
+
+  public static HdfsApi connectToHDFSApi(ViewContext context) {
+    HdfsApi api = null;
+    Thread.currentThread().setContextClassLoader(null);
+
+    String defaultFS = context.getProperties().get("webhdfs.url");
+    if (defaultFS == null) {
+      String message = "webhdfs.url is not configured!";
+      LOG.error(message);
+      throw new MisconfigurationFormattedException("webhdfs.url");
+    }
+
+    try {
+      api = new HdfsApi(defaultFS, getHdfsUsername(context));
+      LOG.info("HdfsApi connected OK");
+    } catch (IOException e) {
+      String message = "HdfsApi IO error: " + e.getMessage();
+      LOG.error(message);
+      throw new ServiceFormattedException(message, e);
+    } catch (InterruptedException e) {
+      String message = "HdfsApi Interrupted error: " + e.getMessage();
+      LOG.error(message);
+      throw new ServiceFormattedException(message, e);
+    }
+    return api;
+  }
+
+  public static String getHdfsUsername(ViewContext context) {
+    String userName = context.getProperties().get("webhdfs.username");
+    if (userName == null || userName.compareTo("null") == 0 || userName.compareTo("") == 0)
+      userName = context.getUsername();
+    return userName;
+  }
+
+  public static void dropAllConnections() {
+    viewSingletonObjects.clear();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/data/pigHelpers.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/data/pigHelpers.json b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/data/pigHelpers.json
new file mode 100644
index 0000000..dbc83cb
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/data/pigHelpers.json
@@ -0,0 +1,128 @@
+[
+      {
+        "title":"Eval Functions",
+        "helpers":[
+          "AVG(%VAR%)",
+          "CONCAT(%VAR1%, %VAR2%)",
+          "COUNT(%VAR%)",
+          "COUNT_START(%VAR%)",
+          "IsEmpty(%VAR%)",
+          "DIFF(%VAR1%, %VAR2%)",
+          "MAX(%VAR%)",
+          "MIN(%VAR%)",
+          "SIZE(%VAR%)",
+          "SUM(%VAR%)",
+          "TOKENIZE(%VAR%, %DELIM%)"
+        ]
+      },
+      {
+        "title":"Relational Operators",
+        "helpers":[
+          "COGROUP %VAR% BY %VAR%",
+          "CROSS %VAR1%, %VAR2%;",
+          "DISTINCT %VAR%;",
+          "FILTER %VAR% BY %COND%",
+          "FLATTEN(%VAR%)",
+          "FOREACH %DATA% GENERATE %NEW_DATA%",
+          "FOREACH %DATA% {%NESTED_BLOCK%}",
+          "GROUP %VAR% BY %VAR%",
+          "GROUP %VAR% ALL",
+          "JOIN %VAR% BY ",
+          "LIMIT %VAR% %N%",
+          "ORDER %VAR% BY %FIELD%",
+          "SAMPLE %VAR% %SIZE%",
+          "SPLIT %VAR1% INTO %VAR2% IF %EXPRESSIONS%",
+          "UNION %VAR1%, %VAR2%"
+        ]
+      },
+      {
+        "title":"I/0",
+        "helpers":[
+          "LOAD \"%FILE%\";",
+          "DUMP %VAR%;",
+          "STORE %VAR% INTO %PATH%;"
+        ]
+      },
+      {
+        "title":"Debug",
+        "helpers":[
+          "EXPLAIN %VAR%;",
+          "ILLUSTRATE %VAR%;",
+          "DESCRIBE %VAR%;"
+        ]
+      },
+      {
+        "title":"HCatalog",
+        "helpers":[
+          "LOAD \"%TABLE%\" USING org.apache.hcatalog.pig.HCatLoader();"
+        ]
+      },
+      {
+        "title":"Math",
+        "helpers":[
+          "ABS(%VAR%)",
+          "ACOS(%VAR%)",
+          "ASIN(%VAR%)",
+          "ATAN(%VAR%)",
+          "CBRT(%VAR%)",
+          "CEIL(%VAR%)",
+          "COS(%VAR%)",
+          "COSH(%VAR%)",
+          "EXP(%VAR%)",
+          "FLOOR(%VAR%)",
+          "LOG(%VAR%)",
+          "LOG10(%VAR%)",
+          "RANDOM(%VAR%)",
+          "ROUND(%VAR%)",
+          "SIN(%VAR%)",
+          "SINH(%VAR%)",
+          "SQRT(%VAR%)",
+          "TAN(%VAR%)",
+          "TANH(%VAR%)"
+        ]
+      },
+      {
+        "title":"Tuple, Bag, Map Functions",
+        "helpers":[
+          "TOTUPLE(%VAR%)",
+          "TOBAG(%VAR%)",
+          "TOMAP(%KEY%, %VALUE%)",
+          "TOP(%topN%, %COLUMN%, %RELATION%)"
+        ]
+      },
+      {
+        "title":"String Functions",
+        "helpers":[
+          "INDEXOF(%STRING%, \"%CHARACTER%\", %STARTINDEX%)",
+          "LAST_INDEX_OF(%STRING%, \"%CHARACTER%\", %STARTINDEX%)",
+          "LOWER(%STRING%)",
+          "REGEX_EXTRACT(%STRING%, %REGEX%, %INDEX%)",
+          "REGEX_EXTRACT_ALL(%STRING%, %REGEX%)",
+          "REPLACE(%STRING%, \"%oldChar%\", \"%newChar%\")",
+          "STRSPLIT(%STRING%, %REGEX%, %LIMIT%)",
+          "SUBSTRING(%STRING%, %STARTINDEX%, %STOPINDEX%)",
+          "TRIM(%STRING%)",
+          "UCFIRST(%STRING%)",
+          "UPPER(%STRING%)"
+        ]
+      },
+      {
+        "title":"Macros",
+        "helpers":[
+          "IMPORT \"%PATH_TO_MACRO%\";"
+        ]
+      },
+      {
+        "title":"HBase",
+        "helpers":[
+          "LOAD \"hbase://%TABLE%\" USING org.apache.pig.backend.hadoop.hbase.HBaseStorage(\"%columnList%\")",
+          "STORE %VAR% INTO \"hbase://%TABLE%\" USING org.apache.pig.backend.hadoop.hbase.HBaseStorage(\"%columnList%\")"
+        ]
+      },
+      {
+        "title":"Python UDF",
+        "helpers":[
+          "REGISTER \"python_udf.py\" USING jython AS myfuncs;"
+        ]
+      }
+    ]

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/FontAwesome.otf
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/FontAwesome.otf b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/FontAwesome.otf
new file mode 100644
index 0000000..81c9ad9
Binary files /dev/null and b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/FontAwesome.otf differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/82e72e51/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.eot
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.eot b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..84677bc0
Binary files /dev/null and b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/fontawesome-webfont.eot differ