2 Achegas b87b6be80c ... 9eeef84ac5

Autor SHA1 Mensaxe Data
  amol 9eeef84ac5 js_libs for cpee %!s(int64=5) %!d(string=hai) anos
  amol 262d3cfdd3 update to latest cpee %!s(int64=5) %!d(string=hai) anos
Modificáronse 55 ficheiros con 4219 adicións e 15 borrados
  1. 7 3
      README.md
  2. 9 3
      Dockerfile
  3. 2 0
      cpee/js_libs/Makefile
  4. 333 0
      cpee/js_libs/ansi_up.js
  5. 80 0
      cpee/js_libs/console.js
  6. 84 0
      cpee/js_libs/custommenu.css
  7. 101 0
      cpee/js_libs/custommenu.js
  8. 4 0
      cpee/js_libs/jquery-2.2.4.min.js
  9. 4 0
      cpee/js_libs/jquery-3.2.1.min.js
  10. 2 0
      cpee/js_libs/jquery-3.3.1.min.js
  11. 40 0
      cpee/js_libs/jquery.browser.js
  12. 10 0
      cpee/js_libs/jquery.caret.min.js
  13. 117 0
      cpee/js_libs/jquery.cookie.js
  14. 2 0
      cpee/js_libs/jquery.min.js
  15. 6 0
      cpee/js_libs/jquery.svg.min.js
  16. 6 0
      cpee/js_libs/jquery.svgdom.min.js
  17. 1 0
      cpee/js_libs/markdown.min.js
  18. 21 0
      cpee/js_libs/parsequery.js
  19. 368 0
      cpee/js_libs/printf.js
  20. 155 0
      cpee/js_libs/relaxngui.css
  21. 427 0
      cpee/js_libs/relaxngui.js
  22. 1 0
      cpee/js_libs/strftime.min.js
  23. 58 0
      cpee/js_libs/tests/dataelements.html
  24. 8 0
      cpee/js_libs/tests/dataelements.rng
  25. 3 0
      cpee/js_libs/tests/dataelements.xml
  26. 59 0
      cpee/js_libs/tests/rngtest1.html
  27. 41 0
      cpee/js_libs/tests/rngtest1.rng
  28. 11 0
      cpee/js_libs/tests/rngtest1.xml
  29. 59 0
      cpee/js_libs/tests/rngtest2.html
  30. 6 0
      cpee/js_libs/tests/rngtest2.rng
  31. 3 0
      cpee/js_libs/tests/rngtest2.xml
  32. 59 0
      cpee/js_libs/tests/rngtest3.html
  33. 23 0
      cpee/js_libs/tests/rngtest3.rng
  34. 9 0
      cpee/js_libs/tests/rngtest3.xml
  35. 59 0
      cpee/js_libs/tests/rngtest4.html
  36. 19 0
      cpee/js_libs/tests/rngtest4.rng
  37. 12 0
      cpee/js_libs/tests/rngtest4.xml
  38. 59 0
      cpee/js_libs/tests/rngtest5.html
  39. 75 0
      cpee/js_libs/tests/rngtest5.rng
  40. 40 0
      cpee/js_libs/tests/rngtest5.xml
  41. 59 0
      cpee/js_libs/tests/rngtest6.html
  42. 24 0
      cpee/js_libs/tests/rngtest6.rng
  43. 6 0
      cpee/js_libs/tests/rngtest6.xml
  44. 59 0
      cpee/js_libs/tests/rngtest8.html
  45. 13 0
      cpee/js_libs/tests/rngtest8.rng
  46. 2 0
      cpee/js_libs/tests/rngtest8.xml
  47. 301 0
      cpee/js_libs/ui.css
  48. 168 0
      cpee/js_libs/ui.html
  49. 172 0
      cpee/js_libs/ui.js
  50. 27 0
      cpee/js_libs/underscore.min.js
  51. 84 0
      cpee/js_libs/util.js
  52. 358 0
      cpee/js_libs/vkbeautify.0.99.00.beta.js
  53. 358 0
      cpee/js_libs/vkbeautify.js
  54. 196 0
      cpee/js_libs/webcomponents.min.js
  55. 9 9
      docker-compose.yml

+ 7 - 3
README.md

@@ -4,8 +4,12 @@ CPEE Dockerfiles for a local installation.
 
 Requirements: Docker and Docker Compose
 
-Put the required CPEE `js_libs` on your host under `/var/www/html/`. If you pick a different path, then also update the `docker-compose.yml`.
+Download this project (zip or clone) and change into the root dir. 
+
+Run `docker-compose up` in a terminal of your choice (Windows: Powershell, Command Prompt; MacOS: Terminal)
+
+Now, in your browser, go to `http://localhost:9090/cpee-cockpit/` and have fun!
+
+
 
-Run `docker build -t "cpee:1.4.26" . `
 
-Run `docker-compose up`

+ 9 - 3
Dockerfile

@@ -1,15 +1,21 @@
 # CPEE Image
 FROM ruby:2.6-alpine
+ENV CPEE_VERSION="1.5.7"
+
 RUN apk add --no-cache --virtual .build-deps \
         ruby-dev \
         rasqal-dev \
         raptor2-dev \
         build-base \
         icu-dev \
-    && gem install cpee -v 1.4.26 \
+    && gem install cpee -v $CPEE_VERSION \
     && apk del .build-deps \
     && apk add libcurl \
-    && ln -s $GEM_HOME/gems/cpee-1.4.26/server /cpee-server \
-    && ln -s $GEM_HOME/gems/cpee-1.4.26/cockpit /cpee-cockpit 
+
+    && cpee new /cpee-server \
+    && cpee cpui /cpee-cockpit
+
 WORKDIR /cpee-server
 CMD ruby server.rb -v start 
+
+

+ 2 - 0
cpee/js_libs/Makefile

@@ -0,0 +1,2 @@
+all:
+	git archive --format=zip --prefix=js_libs/ HEAD -o js_libs.zip

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 333 - 0
cpee/js_libs/ansi_up.js


+ 80 - 0
cpee/js_libs/console.js

@@ -0,0 +1,80 @@
+$(document).ready(function(){
+  var history = 1;
+  var current_command = 1;
+  var dragging = 0;
+  var url = location.href + (location.href.match(/\/$/) ? '' : '/');
+  var ansi_up = new AnsiUp;
+  $('.console-line:last-child .edit').focus();
+  $(document).on('click', '.console-line:last-child', function(e) {
+    $('.console-line:last-child .edit').focus();
+  });
+  $(document).on('keydown', 'body', function(e) {
+    if ((e.ctrlKey && e.keyCode == 86) || !e.ctrlKey) {
+      $('.console-line:last-child .edit').focus();
+    } else {
+      return;
+    }
+    if (e.keyCode == 38) {
+      var anakin = $('.console-line:last-child .edit');
+      if(current_command<history) {
+        current_command++;
+      }
+      anakin.text($(".console-line:nth-last-child("+current_command+") > .edit").text());
+      anakin.focus();
+      jQuery.event.trigger({type:'keyup',which:35,charCode:35,ctrlKey: false});
+      return false;
+    } else if (e.keyCode == 40) {
+      var anakin = $('.console-line:last-child .edit');
+      if(current_command>1) {
+        current_command--;
+      }
+      anakin.html($(".console-line:nth-last-child("+current_command+") > .edit").text());
+    } else if (e.keyCode == 13) {
+      var anakin = $('.console-line:last-child .edit');
+      var anakin_str = anakin.text().split(" ");
+      var command= "";
+      var cc = 0;
+      history++;
+      current_command=1;
+      anakin_str.forEach(function(x){
+        if (cc==0){
+          command="cmd="+x;
+          cc++;
+        } else{
+          command+=" "+x;
+        }
+      });
+      if(anakin_str[0]=="clear"){
+        window.location.reload();
+        return false;
+      }
+      $.ajax({
+        url: url,
+        type: 'get',
+        data: command,
+        success: function(data) {
+          if(jQuery.type(data)=="string"){
+            var appendix = '';
+            appendix += $.trim(data) + "\n";
+            if(anakin_str[0]=="help")
+              appendix+="\033[1m\033[31mclear\033[0m\033[0m\n  Clear screen.";
+            var node = $("<div style='white-space: pre-wrap;'/>");
+                node.html(ansi_up.ansi_to_html(appendix));
+            anakin.parent().append(node);
+          }
+        },
+        error: function(data) {
+          anakin.parent().append("<div>server made a boo boo</div>");
+        },
+        complete: function(data) {
+          var node = $("#console-template").clone().appendTo("body");
+          node.show();
+          node.removeAttr('id');
+          $('.edit:last-child',node).focus();
+        }
+      });
+      anakin.attr('contenteditable',false);
+      return false;
+    }
+  });
+});

+ 84 - 0
cpee/js_libs/custommenu.css

@@ -0,0 +1,84 @@
+/*
+  This file is part of CPEE.
+
+  CPEE is free software: you can redistribute it and/or modify it under the terms
+  of the GNU General Public License as published by the Free Software Foundation,
+  either version 3 of the License, or (at your option) any later version.
+
+  CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  CPEE (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+*/
+
+div.contextmenu, div.menu {
+  padding: 0;
+  margin: 0;
+  z-index: 100000;
+  position: absolute;
+  display:none;
+  background: Menu;
+  border: 1px solid #a1a1a1;
+  -moz-box-sizing:    border-box;
+  -webkit-box-sizing: border-box;
+  box-sizing:         border-box;
+  box-shadow: 0.1em 0.1em 0.1em #a1a1a1;
+}
+
+table.contextmenu {
+  border-collapse:collapse;
+  border-spacing: 0;
+  border: 0 none;
+  padding: 0;
+  margin: 0;
+}
+
+tr.contextmenuheader {
+  font-style:italic;
+  color: #a1a1a1;
+  font-size: small;
+}
+
+tr.contextmenuheader > td{
+  padding-left: 0.5em;
+  padding-right: 1em;
+}
+tr.contextmenuheader:not(:first-child) {
+  border-top: 1px solid #a1a1a1;
+}
+
+div.menu > div {
+  height: 1.5em;
+}
+
+tr.contextmenuitem, div.menu > div {
+  font-size: small;
+  color: #333;
+}
+tr.contextmenuitem:hover, div.menu > div:hover {
+  background-color:Highlight;
+  color: HighlightText;
+}
+tr.contextmenuitem > td, div.menu > div {
+  padding: 0;
+  margin: 0;
+  padding-left: 0.5em;
+  padding-right: 1em;
+}
+tr.contextmenuitem > .contextmenuicon {
+  margin-left: 0.7em;
+  padding-right: 0em;
+}
+tr.contextmenuitem > .contextmenuicon div {
+  height: 1.5em;
+  width: 1.5em;
+  vertical-align:bottom;
+}
+tr.contextmenuitem > .contextmenuicon div svg {
+  height: 1.5em;
+  width: 1.5em;
+  vertical-align:bottom;
+}

+ 101 - 0
cpee/js_libs/custommenu.js

@@ -0,0 +1,101 @@
+/*
+  This file is part of CPEE.
+
+  CPEE is free software: you can redistribute it and/or modify it under the terms
+  of the GNU General Public License as published by the Free Software Foundation,
+  either version 3 of the License, or (at your option) any later version.
+
+  CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  CPEE (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+*/
+
+function CustomMenu(e) {
+  var target = $(e.target);
+  var x = e.pageX;
+  var y = e.pageY;
+  var remove = function(event) {};
+  this.remove = remove;
+  e.stopPropagation();
+
+  this.contextmenu = function(items) {
+    remove = function(event) {
+      if (!event) {
+        $('.contextmenu:first').remove();
+        $('body', document).unbind('mousedown',remove);
+        return;
+      }
+
+      if($(event.target).parent('tr.contextmenuitem') && (event.button == 0)) { $(event.target).click(); }
+      $('.contextmenu:first').remove();
+      $('body', document).unbind('mousedown',remove);
+    }
+    $('body', document).bind('mousedown',remove);
+
+    if($('div.contextmenu').length > 0) remove();
+    var div = $('<div class="contextmenu"><table class="contextmenu"/></div>');
+    for(head in items) {
+      div.children(':first').append('<tr class="contextmenuheader"><td colspan="2">' + head + '</td></tr>');
+      for(item in items[head]) {
+        var icon = null;
+        if(items[head][item].menu_icon) {
+          icon = $X('<svg xmlns="http://www.w3.org/2000/svg" version="1.1">' +
+                      '<g transform="translate(1,1) scale(0.5, 0.5)"/>' +
+                    '</svg>');
+          icon.children('g').append(items[head][item].menu_icon.clone().children());
+          icon = icon.serializeXML();
+        }
+        var row = $('<tr class="contextmenuitem"><td class="contextmenuicon"><div>' + (icon == null ? '' : icon) + '</div></td><td>' + items[head][item].label + '</td></tr>');
+        div.children(':first').append(row);
+        row.bind('click', items[head][item], function(event){
+          event.data.function_call.apply(null, event.data.params);
+        });
+      }
+    }
+    div.css({'left':x+5,'top':y+5, 'display':'block'});
+    $('body', document).append(div);
+    if(($(window).height() < (y + div.height()))) { // contextmenu is position
+      div.css({'top':$(window).height()-div.height()-5});
+    }
+    if((document.body.clientWidth < (x + div.width())) && (x-div.width()-5 >= 0)) { // contextmenu is position
+      div.css({'left':x-div.width()-5});
+    }
+  }
+
+  this.menu = function(menu,call) {
+    remove = function(event) {
+      if ($(event.target).parent('div.menu') && (event.button == 0)) { $(event.target).click(); }
+      menu.hide();
+      $('body', document).unbind('mousedown',remove);
+      $("div.menuitem",$(menu)).each(function(ind,ele){
+        $(ele).unbind('click',mitemclick);
+      });
+    }
+
+    menu.show();
+    var mitemclick = function(ele){
+      $("div.menuitem[data-selected=selected]",$(menu)).each(function(ind,rem){ $(rem).removeAttr('data-selected'); });
+      $(ele.target).attr('data-selected','selected');
+      call(ele.target);
+    };
+    $('body', document).bind('mousedown',remove);
+
+    $("div.menuitem",$(menu)).each(function(ind,ele){
+      $(ele).bind('click',mitemclick);
+    });
+
+    var off = target.offset();
+
+    menu.css({'left':off.left,'top':off.top+target.outerHeight() + 1,'min-width': target.width()});
+    if(($(window).height() < (y + menu.height()))) {
+      menu.css({'top':$(window).height()-menu.height()-5});
+    }
+    if((document.body.clientWidth < (x + menu.width())) && (x-menu.width()-5 >= 0)) {
+      menu.css({'left':x-menu.width()-5});
+    }
+  }
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 4 - 0
cpee/js_libs/jquery-2.2.4.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 4 - 0
cpee/js_libs/jquery-3.2.1.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
cpee/js_libs/jquery-3.3.1.min.js


+ 40 - 0
cpee/js_libs/jquery.browser.js

@@ -0,0 +1,40 @@
+$.browser = {
+  init: function () {
+    this.name = this.searchString(this.dataBrowser) || "Other";
+    this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "Unknown";
+  },
+  searchString: function (data) {
+    for (var i = 0; i < data.length; i++) {
+      var dataString = data[i].string;
+      this.versionSearchString = data[i].subString;
+
+      if (dataString.indexOf(data[i].subString) !== -1) {
+        return data[i].identity;
+      }
+    }
+  },
+  searchVersion: function (dataString) {
+    var index = dataString.indexOf(this.versionSearchString);
+    if (index === -1) {
+      return;
+    }
+
+    var rv = dataString.indexOf("rv:");
+    if (this.versionSearchString === "Trident" && rv !== -1) {
+      return parseFloat(dataString.substring(rv + 3));
+    } else {
+      return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
+    }
+  },
+
+  dataBrowser: [
+    {string: navigator.userAgent, subString: "Chrome", identity: "Chrome"},
+    {string: navigator.userAgent, subString: "MSIE", identity: "Explorer"},
+    {string: navigator.userAgent, subString: "Trident", identity: "Explorer"},
+    {string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
+    {string: navigator.userAgent, subString: "Safari", identity: "Safari"},
+    {string: navigator.userAgent, subString: "Opera", identity: "Opera"}
+  ]
+};
+$.browser.init();    
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 10 - 0
cpee/js_libs/jquery.caret.min.js


+ 117 - 0
cpee/js_libs/jquery.cookie.js

@@ -0,0 +1,117 @@
+/*!
+ * jQuery Cookie Plugin v1.4.0
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2013 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+	if (typeof define === 'function' && define.amd) {
+		// AMD. Register as anonymous module.
+		define(['jquery'], factory);
+	} else {
+		// Browser globals.
+		factory(jQuery);
+	}
+}(function ($) {
+
+	var pluses = /\+/g;
+
+	function encode(s) {
+		return config.raw ? s : encodeURIComponent(s);
+	}
+
+	function decode(s) {
+		return config.raw ? s : decodeURIComponent(s);
+	}
+
+	function stringifyCookieValue(value) {
+		return encode(config.json ? JSON.stringify(value) : String(value));
+	}
+
+	function parseCookieValue(s) {
+		if (s.indexOf('"') === 0) {
+			// This is a quoted cookie as according to RFC2068, unescape...
+			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+		}
+
+		try {
+			// Replace server-side written pluses with spaces.
+			// If we can't decode the cookie, ignore it, it's unusable.
+			s = decodeURIComponent(s.replace(pluses, ' '));
+		} catch(e) {
+			return;
+		}
+
+		try {
+			// If we can't parse the cookie, ignore it, it's unusable.
+			return config.json ? JSON.parse(s) : s;
+		} catch(e) {}
+	}
+
+	function read(s, converter) {
+		var value = config.raw ? s : parseCookieValue(s);
+		return $.isFunction(converter) ? converter(value) : value;
+	}
+
+	var config = $.cookie = function (key, value, options) {
+
+		// Write
+		if (value !== undefined && !$.isFunction(value)) {
+			options = $.extend({}, config.defaults, options);
+
+			if (typeof options.expires === 'number') {
+				var days = options.expires, t = options.expires = new Date();
+				t.setDate(t.getDate() + days);
+			}
+
+			return (document.cookie = [
+				encode(key), '=', stringifyCookieValue(value),
+				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+				options.path    ? '; path=' + options.path : '',
+				options.domain  ? '; domain=' + options.domain : '',
+				options.secure  ? '; secure' : ''
+			].join(''));
+		}
+
+		// Read
+
+		var result = key ? undefined : {};
+
+		// To prevent the for loop in the first place assign an empty array
+		// in case there are no cookies at all. Also prevents odd result when
+		// calling $.cookie().
+		var cookies = document.cookie ? document.cookie.split('; ') : [];
+
+		for (var i = 0, l = cookies.length; i < l; i++) {
+			var parts = cookies[i].split('=');
+			var name = decode(parts.shift());
+			var cookie = parts.join('=');
+
+			if (key && key === name) {
+				// If second argument (value) is a function it's a converter...
+				result = read(cookie, value);
+				break;
+			}
+
+			// Prevent storing a cookie that we couldn't decode.
+			if (!key && (cookie = read(cookie)) !== undefined) {
+				result[name] = cookie;
+			}
+		}
+
+		return result;
+	};
+
+	config.defaults = {};
+
+	$.removeCookie = function (key, options) {
+		if ($.cookie(key) !== undefined) {
+			// Must not alter options, thus extending a fresh object...
+			$.cookie(key, '', $.extend({}, options, { expires: -1 }));
+			return true;
+		}
+		return false;
+	};
+
+}));

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
cpee/js_libs/jquery.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
cpee/js_libs/jquery.svg.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
cpee/js_libs/jquery.svgdom.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
cpee/js_libs/markdown.min.js


+ 21 - 0
cpee/js_libs/parsequery.js

@@ -0,0 +1,21 @@
+jQuery.parseQuery = function(qs) {                                                                                                                                                                                                                                   
+  var q = (typeof qs === 'string' ? qs : window.location.search);
+  var ret = [];
+  q.replace(/#.*$/,'');
+  q.replace(/([^?&=]+)=?([^&]*)(?:&+|$)/g, function(match, key, value) {
+    ret.push( { 'name': decodeURIComponent(key.replace(/\+/g,' ')), 'value': decodeURIComponent(value.replace(/\+/g,' ')) });
+  });
+  return ret;
+}
+jQuery.parseQuerySimple = function(querystring) {
+  var q = jQuery.parseQuery(querystring);
+  var ret = {};
+  jQuery.each(q,function(k,v){
+    ret[v.name] = v.value;
+  });
+  return ret;
+}
+jQuery.parseFragment = function(querystring) {
+  return window.location.hash;
+}
+

+ 368 - 0
cpee/js_libs/printf.js

@@ -0,0 +1,368 @@
+/*##############################################################################
+#    ____________________________________________________________________
+#   /                                                                    \
+#  |               ____  __      ___          _____  /     ___    ___     |
+#  |     ____       /  \/  \  ' /   \      / /      /__   /   \  /   \    |
+#  |    / _  \     /   /   / / /    /  ___/  \__   /     /____/ /    /    |
+#  |   / |_  /    /   /   / / /    / /   /      \ /     /      /____/     |
+#  |   \____/    /   /    \/_/    /  \__/  _____/ \__/  \___/ /           |
+#  |                                                         /            |
+#  |                                                                      |
+#  |   Copyright (c) 2007                             MindStep SCOP SARL  |
+#  |   Herve Masson                                                       |
+#  |                                                                      |
+#  |      www.mindstep.com                              www.mjslib.com    |
+#  |   info-oss@mindstep.com                           mjslib@mjslib.com  |
+#   \____________________________________________________________________/
+#
+#  Version: 1.0.0
+#
+#  (Svn version: $Id: jquery.printf.js 3434 2007-08-27 09:31:20Z herve $)
+#
+#----------[This product is distributed under a BSD license]-----------------
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#
+#     1. Redistributions of source code must retain the above copyright
+#        notice, this list of conditions and the following disclaimer.
+#
+#     2. Redistributions in binary form must reproduce the above copyright
+#        notice, this list of conditions and the following disclaimer in
+#        the documentation and/or other materials provided with the
+#        distribution.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE MINDSTEP CORP PROJECT ``AS IS'' AND
+#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MINDSTEP CORP OR CONTRIBUTORS
+#  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+#  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+#  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+#  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+#  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+#  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#  The views and conclusions contained in the software and documentation
+#  are those of the authors and should not be interpreted as representing
+#  official policies, either expressed or implied, of MindStep Corp.
+#
+################################################################################
+#
+#	This is a jQuery [jquery.com] plugin that implements printf' like functions
+#	(Examples and documentation at: http://mjslib.com)
+#
+#	@author: Herve Masson
+#	@version: 1.0.0 (8/27/2007)
+#	@requires jQuery v1.1.2 or later
+#	
+#	(Based on the legacy mjslib.org framework)
+#
+##############################################################################*/
+
+(function($) {
+
+	/*
+	**	Just an equivalent of the corresponding libc function
+	**
+	**	var str=jQuery.sprintf("%010d %-10s",intvalue,strvalue);
+	**
+	*/
+
+	$.sprintf=function(fmt)
+	{
+		return _sprintf_(fmt,arguments,1);
+	}
+
+
+	/*
+	**	vsprintf takes an argument list instead of a list of arguments (duh!)
+	**	(useful when forwarding parameters from one of your functions to a printf call)
+	**
+	**	str=jQuery.vsprintf(parameters[,offset]);
+	**
+	**		The 'offset' value, when present, instructs vprintf to start at the
+	**		corresponding index in the parameter list instead, of 0
+	**
+	**	Example 1:
+	**
+	**		function myprintf(<printf like arguments>)
+	**		{
+	**			var str=jQuery.vsprintf(arguments);
+	**			..
+	**		}
+	**		myprintf("illegal value : %s",somevalue);
+	**
+	**
+	**	Example 2:
+	**
+	**		function logit(level,<the rest is printf like arguments>)
+	**		{
+	**			var str=jQuery.vsprintf(arguments,1);	// Skip prm #1
+	**			..
+	**		}
+	**		logit("error","illegal value : %s",somevalue);
+	**
+	*/
+
+	$.vsprintf=function(args,offset)
+	{
+		if(offset === undefined)
+		{
+			offset=0;
+		}
+		return _sprintf_(args[offset],args,offset+1);
+	}
+
+
+	/*
+	**	logging using formatted messages
+	**	================================
+	**
+	**	If you _hate_ debugging with alert() as much as I do, you might find the
+	**	following routines valuable.
+	**
+	**	jQuery.alertf("The variable 'str' contains: '%s'",str);
+	**		Show an alert message with a printf-like argument.
+	**
+	**	jQuery.logf("This is a log message, time is: %d",(new Date()).getTime());
+	**		Log the message on the console with the info level
+	**
+	**	jQuery.errorf("The given value (%d) is erroneous",avalue);
+	**		Log the message on the console with the error level
+	**
+	*/
+
+	$.alertf=function()
+	{
+		return alert($.vsprintf(arguments));
+	}
+
+	$.vlogf=function(args)
+	{
+		if("console" in window)
+		{
+			console.info($.vsprintf(args));
+		}
+	}
+
+	$.verrorf=function(args)
+	{
+		if("console" in window)
+		{
+			console.error($.vsprintf(args));
+		}
+	}
+
+	$.errorf=function()
+	{
+		$.verrorf(arguments);
+	}
+
+	$.logf=function()
+	{
+		$.vlogf(arguments);
+	}
+
+
+	/*-------------------------------------------------------------------------------------------
+	**
+	**	Following code is private; don't use it directly !
+	**
+	**-----------------------------------------------------------------------------------------*/
+
+	FREGEXP	= /^([^%]*)%([-+])?(0)?(\d+)?(\.(\d+))?([doxXcsf])(.*)$/;
+	HDIGITS	= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
+
+	function _empty(str)
+	{
+		if(str===undefined || str===null)
+		{
+			return true;
+		}
+		return (str == "") ? true : false;
+	}
+
+	function _int_(val)
+	{
+		return Math.floor(val);
+	}
+
+	function _printf_num_(val,base,pad,sign,width)
+	{
+		val=parseInt(val,10);
+		if(isNaN(val))
+		{
+			return "NaN";
+		}
+		aval=(val<0)?-val:val;
+		var ret="";
+
+		if(aval==0)
+		{
+			ret="0";
+		}
+		else
+		{
+			while(aval>0)
+			{
+				ret=HDIGITS[aval%base]+ret;
+				aval=_int_(aval/base);
+			}
+		}
+		if(val<0)
+		{
+			ret="-"+ret;
+		}
+		if(sign=="-")
+		{
+			pad=" ";
+		}
+		return _printf_str_(ret,pad,sign,width,-1);
+	}
+
+	function _printf_float_(val,base,pad,sign,prec)
+	{
+		if(prec==undefined)
+		{
+			if(parseInt(val) != val)
+			{
+				// No decimal part and no precision -> use int formatting
+				return ""+val;
+			}
+			prec=5;
+		}
+
+		var p10=Math.pow(10,prec);
+		var ival=""+Math.round(val*p10);
+		var ilen=ival.length-prec;
+		if(ilen==0)
+		{
+			return "0."+ival.substr(ilen,prec);
+		}
+		return ival.substr(0,ilen)+"."+ival.substr(ilen,prec);
+	}
+
+	function _printf_str_(val,pad,sign,width,prec)
+	{
+		var npad;
+
+		if(val === undefined)
+		{
+			return "(undefined)";
+		}
+		if(val === null)
+		{
+			return "(null)";
+		}
+		if((npad=width-val.length)>0)
+		{
+			if(sign=="-")
+			{
+				while(npad>0)
+				{
+					val+=pad;
+					npad--;
+				}
+			}
+			else
+			{
+				while(npad>0)
+				{
+					val=pad+val;
+					npad--;
+				}
+			}
+		}
+		if(prec>0)
+		{
+			return val.substr(0,prec);
+		}
+		return val;
+	}
+
+	function _sprintf_(fmt,av,index)
+	{
+		var output="";
+		var i,m,line,match;
+
+		line=fmt.split("\n");
+		for(i=0;i<line.length;i++)
+		{
+			if(i>0)
+			{
+				output+="\n";
+			}
+			fmt=line[i];
+			while(match=FREGEXP.exec(fmt))
+			{
+				var sign="";
+				var pad=" ";
+
+				if(!_empty(match[1])) // the left part
+				{
+					// You can't add this blindly because mozilla set the value to <undefined> when
+					// there is no match, and we don't want the "undefined" string be returned !
+					output+=match[1];
+				}
+				if(!_empty(match[2])) // the sign (like in %-15s)
+				{
+					sign=match[2];
+				}
+				if(!_empty(match[3])) // the "0" char for padding (like in %03d)
+				{
+					pad="0";
+				}
+
+				var width=match[4];	// the with (32 in %032d)
+				var prec=match[6];	// the precision (10 in %.10s)
+				var type=match[7];	// the parameter type
+
+				fmt=match[8];
+
+				if(index>=av.length)
+				{
+					output += "[missing parameter for type '"+type+"']";
+					continue;
+				}
+
+				var val=av[index++];
+
+				switch(type)
+				{
+				case "d":
+					output += _printf_num_(val,10,pad,sign,width);
+					break;
+				case "o":
+					output += _printf_num_(val,8,pad,sign,width);
+					break;
+				case "x":
+					output += _printf_num_(val,16,pad,sign,width);
+					break;
+				case "X":
+					output += _printf_num_(val,16,pad,sign,width).toUpperCase();
+					break;
+				case "c":
+					output += String.fromCharCode(parseInt(val,10));
+					break;
+				case "s":
+					output += _printf_str_(val,pad,sign,width,prec);
+					break;
+				case "f":
+					output += _printf_float_(val,pad,sign,width,prec);
+					break;
+				default:
+					output += "[unknown format '"+type+"']";
+					break;
+				}
+			}
+			output+=fmt;
+		}
+		return output;
+	}
+
+})(jQuery);
+
+

+ 155 - 0
cpee/js_libs/relaxngui.css

@@ -0,0 +1,155 @@
+/*
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+*/
+
+.relaxngui_table { }
+.relaxngui_table .relaxngui_table { }
+
+.relaxngui_table > .relaxngui_table > .relaxngui_table {
+  padding: 0;
+  padding-top: 0.2em;
+  padding-bottom: 0.5em;
+  padding-left: 1em;
+}
+.relaxngui_dyn {
+  margin: 0;
+  padding: 0;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding-bottom: 0.25em;
+  padding-top: 0.25em;
+  margin-left: 0.5em;
+}
+.relaxngui_dyn > *:nth-child(1) {
+  margin: 0;
+  padding: 0;
+  font-size: 1em;
+  margin-right: 0.2em;
+  margin-left: 0.2em;
+  vertical-align: baseline;
+  cursor: pointer;
+  display: inline-block;
+}
+.relaxngui_dyn > *:nth-child(2) {
+  flex: 1 1 auto;
+}
+
+.relaxngui_dyn > .relaxngui_table { padding: 0; margin: 0; }
+.relaxngui_dyn:nth-child(even) { background-color: #fff; }
+.relaxngui_dyn:nth-child(odd)  { background-color: #e9e9e9; }
+.relaxngui_table.even > .relaxngui_row:nth-child(even) { background-color: #fff; }
+.relaxngui_table.even > .relaxngui_row:nth-child(odd)  { background-color: #e9e9e9; }
+.relaxngui_table.odd  > .relaxngui_row:nth-child(even) { background-color: #e9e9e9; }
+.relaxngui_table.odd  > .relaxngui_row:nth-child(odd)  { background-color: #fff; }
+.relaxngui_table.even > .relaxngui_hint:nth-child(odd) { background-color: #fff; }
+.relaxngui_table.even > .relaxngui_hint:nth-child(even)  { background-color: #e9e9e9; }
+.relaxngui_table.odd  > .relaxngui_hint:nth-child(odd)  { background-color: #e9e9e9; }
+.relaxngui_table.odd  > .relaxngui_hint:nth-child(even)  { background-color: #fff; }
+
+.relaxngui_dyn:nth-child(even) > .relaxngui_table > .relaxngui_row:nth-child(1):nth-last-child(1) {
+  background-color: #fff;
+}
+.relaxngui_dyn:nth-child(odd) > .relaxngui_table > .relaxngui_row:nth-child(1):nth-last-child(1) {
+  background-color: #e9e9e9;
+}
+
+.relaxngui_table.even { background-color: #e9e9e9; }
+.relaxngui_table.odd  { background-color: #fff; }
+
+.relaxngui_row {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+}
+.relaxngui_hint {
+  padding-left: 0.2em;
+}
+.relaxngui_hint::before {
+ 	content: "↳ ";
+}
+.relaxngui_header {
+  margin: 0;
+  padding: 0;
+  padding-top: 0.7em;
+  padding-bottom: 0.2em;
+  padding-left: 0.1em;
+  display: block;
+  font-weight: bold;
+  font-size: 1.2em;
+}
+.relaxngui_dyn .relaxngui_header {
+  font-size: 1em;
+}
+button.relaxngui_control {
+  margin: 0.5em 0;
+  align-self: flex-start;
+}
+
+.relaxngui_cell { }
+
+.relaxngui_cell.optional { text-decoration: line-through; }
+
+.relaxngui_cell:nth-child(1), .relaxngui_cell:nth-child(2) {
+  margin: 0;
+  padding: 0.1em 0.2em;
+  font-size: 1em;
+  font-family: sans-serif;
+}
+input.relaxngui_cell:nth-child(1) {
+  border: 0 none;
+  background: none;
+}
+.relaxngui_cell:nth-child(3) {
+  margin: 0;
+  padding: 0.1em 0.2em;
+  flex: 1 1 auto;
+  font-size: 1em;
+  font-family: sans-serif;
+}
+select.relaxngui_cell:nth-child(3) {
+  -webkit-appearance: none;  /*Removes default chrome and safari style*/
+  -moz-appearance: none; /* Removes Default Firefox style*/
+  padding: 0;
+}
+select.relaxngui_cell:nth-child(3), button.relaxngui_cell:nth-child(3), textarea.relaxngui_cell:nth-child(3), input.relaxngui_cell:nth-child(3), [contenteditable].relaxngui_cell:nth-child(3) {
+  border: 0 none;
+  background: none;
+}
+
+[contenteditable].relaxngui_cell:nth-child(3) {
+  overflow-x: auto;
+  overflow-wrap: normal;
+  white-space: pre;
+  font-family: monospace,monospace;
+}
+[contenteditable][data-relaxngui-wrap='true'].relaxngui_cell:nth-child(3) {
+  white-space: normal;
+}
+[contenteditable].relaxngui_cell:focus {
+  outline: 0px solid transparent;
+}
+[contenteditable].relaxngui_cell:empty:before {
+  font-family: sans-serif;
+  color: #a1a1a1;
+  white-space: normal;
+  content: attr(placeholder);
+  display: block;
+}
+
+.relaxngui_template {
+  display: none;
+}

+ 427 - 0
cpee/js_libs/relaxngui.js

@@ -0,0 +1,427 @@
+/*
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+*/
+
+var RelaxNGui = function(rng,target,ceval,ignore=false) {
+  if (!(rng instanceof XMLDocument)) { // rng has to be XMLDocument //{{{
+    rng = $XR($(rng).serializeXML());
+  } //}}}
+
+  var lenextract = function(tag, lencount) { //{{{
+    $.each(tag.attributes,function(k,v){
+      if ((v.localName == 'label') && (v.namespaceURI == 'http://rngui.org')) { lencount = v.nodeValue.length > lencount ? v.nodeValue.length : lencount; }
+    });
+    return lencount;
+  }; //}}}
+
+  var labextract = function(type,tag) { //{{{
+    var ret = { 'type': type, 'wrap': false, 'readonly': false, 'label': '', default: '' };
+    $.each(tag.attributes,function(k,v){
+      if ((v.localName == 'label') && (v.namespaceURI == 'http://rngui.org')) { ret['label'] = v.nodeValue; }
+      if ((v.localName == 'readonly') && (v.namespaceURI == 'http://rngui.org')) { ret['readonly'] = v.nodeValue == 'true' ? true : false; }
+      if ((v.localName == 'wrap') && (v.namespaceURI == 'http://rngui.org')) { ret['wrap'] = v.nodeValue == 'true' ? true : false; }
+    });
+    $.each(tag.children,function(k,v){
+      if ((v.localName == 'param') && (v.namespaceURI == 'http://relaxng.org/ns/structure/1.0')) {
+        $.each(v.attributes,function(l,w){
+          if ((w.localName == 'name') && (w.nodeValue == 'minInclusive')) {
+            ret['min'] = v.lastChild.nodeValue;
+          }
+          if ((w.localName == 'name') && (w.nodeValue == 'maxInclusive')) {
+            ret['max'] = v.lastChild.nodeValue;
+          }
+        });
+      }
+    });
+    return ret;
+  }; //}}}
+
+  var addelements = function(target) { //{{{
+    var template = target.parent().find('> .relaxngui_template').clone(true,true);
+    template.removeClass('relaxngui_template');
+    template.find('[data-relaxngui-template]').each(function(j,t){
+      $(t).attr('data-relaxngui-template',false);
+    });
+    template.find('.relaxngui_template [data-relaxngui-template]').each(function(j,t){
+      $(t).attr('data-relaxngui-template',true);
+    });
+    template.addClass('relaxngui_dyn');
+    template.on('click', '> *:first-child', function(ev){ delelements($(ev.target)); });
+
+    if (target.parent().find('> .relaxngui_dyn').length % 2 == 1) {
+      var evens = template.find('.even');
+      var odds = template.find('.odd');
+      evens.each(function(k,v){
+        $(v).removeClass('even');
+        $(v).addClass('odd');
+      });
+      odds.each(function(k,v){
+        $(v).removeClass('odd');
+        $(v).addClass('even');
+      });
+    }
+
+    target.parent().find('> .relaxngui_control').before(template);
+  }; //}}}
+
+  var delelements = function(target) { //{{{
+    var it = target.parent();
+    var par = target.parent().parent();
+    it.remove();
+    par.trigger('relaxngui_remove');
+  }; //}}}
+
+  var recshow_header = function(tag,ret){ //{{{
+    var header;
+    $.each(tag.attributes,function(k,v){
+      if ((v.localName == 'header') && (v.namespaceURI == 'http://rngui.org')) { header = v.nodeValue; }
+    });
+    if (header) {
+      ret.append($("<div class='relaxngui_header'>" + header + "</div>"));
+    }
+  } //}}}
+
+  var recshow_single = function(tag,ret,template,path,lencount,optional){ //{{{
+    var node = $('<div class="relaxngui_row"/>');
+    var name;
+    var label;
+    var second = {};
+    var datalist = [];
+    var defaul = '';
+    var hint = '';
+    var retcount = 0;
+    $.each(tag.attributes,function(k,v){
+      if ((v.localName == 'label')   && (v.namespaceURI == 'http://rngui.org')) { label  = v.nodeValue; }
+      if ((v.localName == 'date')    && (v.namespaceURI == 'http://rngui.org')) { label  = v.nodeValue; }
+      if ((v.localName == 'default') && (v.namespaceURI == 'http://rngui.org')) { defaul = v.nodeValue; }
+      if ((v.localName == 'hint')    && (v.namespaceURI == 'http://rngui.org')) { hint   = v.nodeValue; }
+      if  (v.localName == 'name')                                               { name   = v.nodeValue; }
+    });
+
+    $.each($(tag).children('data[type=string]'), function(k,v) { second = labextract('string',v); });
+    $.each($(tag).children('data[type=integer]'), function(k,v) { second = labextract('integer',v); });
+    $.each($(tag).children('data[type=nonNegativeInteger]'), function(k,v) { second = labextract('nonNegativeInteger',v); });
+    $.each($(tag).children('data[type=positiveInteger]'), function(k,v) { second = labextract('positiveInteger',v); });
+    $.each($(tag).children('data[type=float]'), function(k,v) { second = labextract('float',v); });
+    $.each($(tag).children('data[type=date]'), function(k,v) { second = labextract('date',v); });
+    $.each($(tag).children('text'), function(k,v) { second = labextract('text',v); });
+    $.each($(tag).find('choice > value'), function(k,v) {
+      second = labextract('datalist',$(v).parent()[0]);
+      datalist.push(v.textContent);
+    });
+    if (name && label) {
+      node.append($("<label class='relaxngui_cell" + (optional && defaul == '' ? " optional": "") + "' style='min-width: " + (lencount+1) + "ex' for=''>" + label + "</label><span class='relaxngui_cell'>⇒</span>"));
+    } else if (name) {
+      // a tag without information is ignored
+    } else if (label) {
+      node.append($("<input data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + path + " > *[data-name]' class='relaxngui_cell' type='text' pattern='^[a-z][a-zA-Z0-9_]*$' id='' placeholder='" + label + "'></input><span class='relaxngui_cell'>⇒</span>"));
+    }
+
+    var tpath = ((typeof name === 'undefined') ? path + ' > *' : (tag.localName == 'element' ? path + ' > ' + $(tag).attr('name') : path + '[' + $(tag).attr('name') + ']'));
+    if (label) {
+      if (defaul && typeof defaul == 'string' && defaul.match(/^javascript:/)) {
+        defaul = defaul.replace(/^javascript:/,'');
+        defaul = ceval ? ceval(defaul) : eval(defaul);
+      }
+      var os = (optional ? " onkeyup='var sl = $(this).siblings(\"label\"); if ($(this).get_val() == \"\") { if (!sl.hasClass(\"optional\")) { sl.addClass(\"optional\") } } else { sl.removeClass(\"optional\") }' data-optional='true'" : " data-optional='false'");
+      if (second.readonly)
+        node.append($("<input      " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='text'              id='' readonly='readonly'" + os + "></input>"));
+      else {
+        if (second.type == 'string') {
+          node.append($("<input    " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='text'              id='' placeholder='" + second.label + "'" + os + "></input>"));
+        } else if (second.type == 'integer') {
+          node.append($("<input    " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='number'            id='' placeholder='" + second.label + "'" + (second.min != undefined ? (" min='" + second.min + "'") : '') + (second.max != undefined ? (" max='" + second.max + "'") : '') + os + "></input>"));
+        } else if (second.type == 'positiveInteger') {
+          if (second.min == undefined) second.min = 1;
+          node.append($("<input    " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='number'            id='' placeholder='" + second.label + "'" + (second.min != undefined ? (" min='" + second.min + "'") : '') + (second.max != undefined ? (" max='" + second.max + "'") : '') + os + "></input>"));
+        } else if (second.type == 'nonNegativeInteger') {
+          if (second.min == undefined) second.min = 0;
+          node.append($("<input    " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='number'            id='' placeholder='" + second.label + "'" + (second.min != undefined ? (" min='" + second.min + "'") : '') + (second.max != undefined ? (" max='" + second.max + "'") : '') + os + "></input>"));
+        } else if (second.type == 'date') {
+          node.append($("<input    " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='date'              id='' placeholder='" + second.label + "'" + os + "></input>"));
+        } else if (second.type == 'float') {
+          node.append($("<input    " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell' type='number' step='any' id='' placeholder='" + second.label + "'" + (second.min != undefined ? (" min='" + second.min + "'") : '') + (second.max != undefined ? (" max='" + second.max + "'") : '') + os + "></input>"));
+        } else if (second.type == 'text') {
+          node.append($("<div contenteditable='true' data-relaxngui-wrap='" + second.wrap + "' " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell'               id='' placeholder='" + second.label + "'" + os + "></div>"));
+        } else if (second.type == 'datalist') {
+          var tnode = $("<select   " + (defaul && typeof defaul == 'string' ? 'value="' + defaul + '"' : '') + " data-relaxngui-template='" + template + "' data-relaxngui-parent='" + path + "' data-relaxngui-path='" + tpath + "' class='relaxngui_cell'               id='' size='1'" + os + "></select>");
+          $.each(datalist,function(didx,dname){
+            if (dname == defaul)
+              tnode.append('<option value="' + dname + '" selected="selected">' + dname + '</value>');
+            else
+              tnode.append('<option value="' + dname + '">' + dname + '</value>');
+          });
+          node.append(tnode);
+        }
+      }
+      ret.append(node);
+      retcount += 1;
+    } else {
+      if (tag.localName != 'element') { // its an attribute, simulate its empty-ness
+        node.attr('data-relaxngui-template',template);
+        node.attr('data-relaxngui-parent',path);
+        node.attr('data-relaxngui-path',tpath);
+        ret.append(node);
+        retcount += 1;
+      }
+    }
+    if (hint) {
+      var n  = $('<div class="relaxngui_hint"/>');
+      var s1 = $('<em>Hint: </em>');
+      var s2 = $('<span/>');
+          s2.text(hint);
+
+      n.append(s1);
+      n.append(s2);
+      ret.append(n);
+      retcount += 1;
+    }
+    return retcount;
+  } //}}}
+
+  var recshow = function(elements,template,path,attr) { //{{{
+    // delete all elements with relaxngui:ignore
+    if (attr.ignore) {
+      var tele = $.grep(elements,function(tagv){
+        var include = true;
+        $.each(tagv.attributes,function(k,v){
+          if ((v.localName == 'ignore') && (v.namespaceURI == 'http://rngui.org')) {
+            include = false;
+          }
+        });
+        return include;
+      });
+      elements = $(tele);
+    }
+
+    var ret = $('<div/>');
+
+    var lencount = 0;
+    $.each(elements,function(k,v){
+      var tag = $(v)[0];
+      if ((tag.localName == 'element') && (tag.namespaceURI == 'http://relaxng.org/ns/structure/1.0')) {
+        $(tag).children('attribute').each(function(l,w){
+          lencount = lenextract($(w)[0],lencount);
+        });
+        lencount = lenextract(tag,lencount);
+      }
+    });
+    $.each(elements,function(k,v){
+      if (attr.mode == 'even') { attr.mode = 'odd' }
+      else { attr.mode = 'even'; }
+
+      var tag = $(v)[0];
+
+      if ((tag.localName == 'element') && (tag.namespaceURI == 'http://relaxng.org/ns/structure/1.0')) {
+        var xxx;
+        if (template) {
+          var yyy = $('<div class="relaxngui_table ' + attr.mode + '" data-relaxngui-template="true" data-relaxngui-parent="' + path + '" data-relaxngui-path="' + (path == '' ? ' > '  + (typeof elements.attr('name') === 'undefined' ? '*' : elements.attr('name')) : path + ' > ' + (typeof $(tag).attr('name') === 'undefined' ? '*' : $(tag).attr('name'))) + '[data-main]">');
+          xxx = $('<div class="relaxngui_template"><span>✖</span></div>');
+          xxx.append(yyy);
+          ret.append(xxx);
+          xxx = yyy;
+        } else {
+          xxx = $('<div class="relaxngui_table ' + attr.mode + '" data-relaxngui-template="false" data-relaxngui-parent="' + path + '" data-relaxngui-path="' + (path == '' ? ' > '  + elements.attr('name') : path + ' > ' + $(tag).attr('name')) + '[data-main]">');
+          ret.append(xxx);
+        }
+
+        recshow_header(tag,xxx);
+        var rcount = 0;
+        $(tag).children('attribute').each(function(l,w){
+          var ttag = $(w)[0];
+          rcount += recshow_single(ttag,xxx,template,path + ' > ' + $(tag).attr('name'),lencount,attr.optional ? true : false);
+        });
+        rcount += recshow_single(tag,xxx,template,path,lencount,attr.optional ? true : false);
+
+        var sub;
+        if (sub = recshow($(tag).children('element, zeroOrMore, optional'),false,path + ' > ' + $(tag).attr('name'),{ ignore: attr.ignore, mode: (attr.mode == 'even' && rcount % 2 == 0 ? 'odd' : 'even' ) })) {
+          var inode = xxx.append(sub);
+          if (template) {
+            inode.find('[data-relaxngui-template]').each(function(j,t){
+              $(t).attr('data-relaxngui-template',true);
+            });
+          }
+        }
+      } else if ((tag.localName == 'zeroOrMore') && (tag.namespaceURI == 'http://relaxng.org/ns/structure/1.0')) {
+        var label;
+        $.each(tag.attributes,function(k,v){
+          if ((v.localName == 'label') && (v.namespaceURI == 'http://rngui.org')) { label = v.nodeValue; }
+        });
+        var but = $('<button class="relaxngui_control">' + label + '</button>');
+            but.on('click',function(ev){ addelements($(ev.target)); });
+
+        ret.append(recshow($(tag).children(),true,path,{ ignore: attr.ignore, mode: attr.mode }));
+        ret.append(but);
+      } else if ((tag.localName == 'optional') && (tag.namespaceURI == 'http://relaxng.org/ns/structure/1.0')) {
+        ret.append(recshow($(tag).children('element, zeroOrMore'),false,path,{ ignore: attr.ignore, mode: (attr.mode == 'even' ? 'odd' : 'even'), optional: true }));
+      }
+    });
+    return ret.children().length > 0 ? ret.children() : undefined;
+  }; //}}}
+
+  var serializeXML = function (xml) { //{{{
+    var out = '';
+    if (typeof XMLSerializer == 'function') {
+        var xs = new XMLSerializer();
+        $(xml).each(function() {
+            out += xs.serializeToString(this);
+        });
+    } else if (xml && xml.xml != 'undefined') {
+        $(xml).each(function() {
+            out += this.xml;
+        });
+    }
+    return out;
+  }; //}}}
+  this.save = function() { //{{{
+    var xml;
+    var curr;
+    var tar = target.find('[data-relaxngui-path]:not([data-relaxngui-template=true])');
+    for (var i = 0; i<tar.length;) {
+      var path = $(tar[i]).attr('data-relaxngui-path');
+      var parent_path = $(tar[i]).attr('data-relaxngui-parent');
+      if (i == 0) {
+        var par = path.replace(/\[data-main\]/,'').replace(/ > /,'');
+        xml = $XR('<' + par + '/>');
+      } else {
+        var ma = path.match(/([^\s]+)$/)[1];
+        var att;
+        if (ma.match(/\*\[data-main\]/)) {
+          // do nothing. seriously. explicitly.
+        } else if (ma.match(/\[data-main\]/)) {
+          var par = ma.replace(/\[data-main\]/,'');
+          var curr = $($XR('<' + par + '/>').documentElement);
+          $(parent_path,xml).last().append(curr);
+        } else if (ma.match(/\[data-name\]/)) {
+          if ($(tar[i]).get_val()) {
+            var nn =  $($XR('<' + $(tar[i]).get_val() + '/>').documentElement).text($(tar[i+1]).get_val());
+            $(parent_path,xml).append(nn);
+          }
+          i+=1;
+        } else if (att = ma.match(/\[([^\]]+)\]$/)) {
+          $(parent_path + ':last-child',xml).last().attr(att[1],$(tar[i]).get_val());
+        } else {
+          if ($(tar[i]).attr('data-optional') == 'true' && $(tar[i]).get_val() == '') {
+            $(path + ':last-child',xml).last().remove();
+          } else {
+            $(path + ':last-child',xml).last().text($(tar[i]).get_val())
+          }
+        }
+      }
+      i+=1;
+    }
+    return xml;
+  }; //}}}
+  this.save_text = function() { //{{{
+    return serializeXML(self.save());
+  } //}}}
+
+  this.content = function(data) { //{{{
+    if (!(data instanceof XMLDocument)) { // data has to be XMLDocument //{{{
+      data = $XR($(data).serializeXML());
+    } //}}}
+
+    if (data) {
+      var x = $(data).serializePrettyXML();
+      x = x.replace(/\s+xmlns(:[a-zA-Z0-9]+)?=\"[^\"]+\"/g, "");
+      x = x.replace(/<\?[^>]+>/g, "");
+      x = x.trim();
+      y = $(self.save()).serializePrettyXML();
+      if (x != y) {
+        target.find('.relaxngui_dyn').remove();
+        target.find('[data-relaxngui-path]').each(function(k,pa){
+          var path = $(pa).attr('data-relaxngui-path');
+          if (!path.match(/data-\w+\]$/)) {
+            if ($(pa).attr('data-relaxngui-template') == 'true' && path.match(/\*$/)) {
+              $(data).find(path).each(function(index,ele){
+                $(target.find('[data-relaxngui-path="' + path + '[data-name]"][data-relaxngui-template="false"]').get(index)).set_val(ele.localName);
+                $(target.find('[data-relaxngui-path="' + path + '"][data-relaxngui-template="false"]').get(index)).set_val($(ele).text());
+              });
+            } else if ($(pa).attr('data-relaxngui-template') == 'true' && !path.match(/\*$/)) {
+              $(data).find(path).each(function(index,ele){
+                var att;
+                var val;
+                if (att = path.match(/(.*)\[([^\]]+)\]$/)) {
+                  val = $(ele).attr(att[2]);
+                } else {
+                  val = $(ele).text();
+                }
+                if (val && val != '') {
+                  $(target.find('[data-relaxngui-path="' + path + '"][data-relaxngui-template="false"]').get(index)).set_val(val);
+                }
+              });
+            } else {
+              var att;
+              var val;
+              if (att = path.match(/(.*)\[([^\]]+)\]$/)) {
+                val = $(data).find(att[1]).attr(att[2]);
+              } else {
+                val = $(data).find(path).text();
+              }
+              if (val && val != '') {
+                var t = target.find('[data-relaxngui-path="' + path + '"]');
+                t.set_val(val);
+                if (t.attr('data-optional') == 'true') {
+                  t.siblings('label').removeClass('optional');
+                }
+              }
+            }
+          } else {
+            if ($(pa).attr('data-relaxngui-template') == 'true') {
+              var but = target.find('.relaxngui_table[data-relaxngui-template="false"] > .relaxngui_template > [data-relaxngui-path="' + path + '"][data-relaxngui-template="true"]').parent().parent().find('> button');
+              if (but.length > 0) {
+                var dpath = path.replace(/\[data-main\]$/,'');
+                var par = undefined;
+                var ind = -1;
+                $(data).find(dpath).each(function(ke,ele){
+                  if (par != $(ele).parent()[0]) {
+                    ind += 1;
+                    par = $(ele).parent()[0];
+                  }
+                  if ($(but.get(ind)).attr('disabled')) {
+                    $(but.get(ind)).removeAttr('disabled');
+                    but.get(ind).click();
+                    $(but.get(ind)).attr('disabled','disabled');
+                  } else {
+                    but.get(ind).click();
+                  }
+                });
+              }
+            }
+          }
+        });
+        self.set_checkpoint();
+      }
+    }
+  }; //}}}
+
+  // stuff to determine if user changed something
+  var orig = '';
+  this.set_checkpoint = function() { //{{{
+    orig = self.save_text();
+  } //}}}
+  this.has_changed = function() { //{{{
+    if (orig != self.save_text()) {
+      return true;
+    } else {
+      return false;
+    }
+  } //}}}
+
+  target.append(recshow($(rng.documentElement),false,'',{ ignore: ignore, mode: 'even'}));
+
+  var self = this;
+};

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
cpee/js_libs/strftime.min.js


+ 58 - 0
cpee/js_libs/tests/dataelements.html

@@ -0,0 +1,58 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Dataelements</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="http://localhost/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="http://localhost/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet" href="http://localhost/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="http://localhost/js_libs/util.js"></script>
+    <script type="text/javascript" src="http://localhost/js_libs/vkbeautify.js"></script>
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "dataelements.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "dataelements.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 8 - 0
cpee/js_libs/tests/dataelements.rng

@@ -0,0 +1,8 @@
+<element rngui:version="1.2" name="value" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <zeroOrMore rngui:label="Create Data Element">
+    <element rngui:label='Name'>
+      <anyName/>
+      <data type="string" rngui:label="Value"/>
+    </element>
+  </zeroOrMore>
+</element>

+ 3 - 0
cpee/js_libs/tests/dataelements.xml

@@ -0,0 +1,3 @@
+<value>
+  <a>b</a>
+</value>

+ 59 - 0
cpee/js_libs/tests/rngtest1.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 1</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest1.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest1.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 41 - 0
cpee/js_libs/tests/rngtest1.rng

@@ -0,0 +1,41 @@
+<element rngui:version="1.2" name="call" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <attribute name="id" rngui:label="ID">
+    <data type="string" rngui:readonly="true" rngui:default="javascript:generate_id()"/>
+  </attribute>
+  <attribute name="endpoint" rngui:label="Endpoint">
+    <data type="string"/>
+  </attribute>
+  <element name='parameters' rngui:header="Parameters">
+    <element name="label" rngui:label="Label">
+      <data type="string" rngui:label="Short description of the task"/>
+    </element>
+    <element name="method" rngui:label="Method">
+      <choice>
+        <value>:post</value>
+        <value>:get</value>
+        <value>:put</value>
+        <value>:delete</value>
+      </choice>
+    </element>
+    <element name="arguments" rngui:header="Arguments">
+      <zeroOrMore rngui:label="Create Argument Pair">
+        <element rngui:label='Name'>
+          <anyName/>
+          <data type="string" rngui:label="Value"/>
+        </element>
+      </zeroOrMore>
+    </element>
+  </element>
+  <element name="finalize" rngui:header="Finalize" rngui:label="Code">
+    <attribute name="output" rngui:label="Access Variable">
+      <data type="string" rngui:readonly="true" rngui:default="result"/>
+    </attribute>
+    <text rngui:label='Script that is executed, when a service returns data'/>
+  </element>
+  <element name="update" rngui:header="Update" rngui:label="Code">
+    <attribute name="output" rngui:label="Access Variable">
+      <data type="string" rngui:readonly="true" rngui:default="result"/>
+    </attribute>
+    <text rngui:label='Script that is executed, when a service sends intermediate data'/>
+  </element>
+</element>

+ 11 - 0
cpee/js_libs/tests/rngtest1.xml

@@ -0,0 +1,11 @@
+<call id="a1" endpoint="timeout">
+  <parameters>
+    <label></label>
+    <method>:post</method>
+    <arguments>
+      <timeout>2</timeout>
+    </arguments>
+  </parameters>
+  <finalize output="result">  data.x += "a1,"</finalize>
+  <update output="result">  data.x += "a1,"</update>
+</call>

+ 59 - 0
cpee/js_libs/tests/rngtest2.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 2</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest2.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest2.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 6 - 0
cpee/js_libs/tests/rngtest2.rng

@@ -0,0 +1,6 @@
+<element rngui:version="1.2" name="manipulate" rngui:label="Script" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <attribute name="id" rngui:label="ID">
+    <data type="string" rngui:readonly="true" rngui:default="javascript:generate_id()"/>
+  </attribute>
+  <text rngui:label='Script that is executed'/>
+</element>

+ 3 - 0
cpee/js_libs/tests/rngtest2.xml

@@ -0,0 +1,3 @@
+<manipulate id="a1">
+  data.x += "a1,"
+</manipulate>

+ 59 - 0
cpee/js_libs/tests/rngtest3.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 3</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest3.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest3.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 23 - 0
cpee/js_libs/tests/rngtest3.rng

@@ -0,0 +1,23 @@
+<element rngui:version="1.2" name="call" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <element name="arguments" rngui:header="Arguments">
+    <zeroOrMore rngui:label="Create Argument Pair">
+      <element rngui:label='Name'>
+        <anyName/>
+        <data type="string" rngui:label="Value"/>
+      </element>
+    </zeroOrMore>
+  </element>
+  <element name="_attachments">
+    <zeroOrMore rngui:label="Create Attachment">
+      <element name='_attachment' rngui:label='Attachment'>
+        <attribute name="label" rngui:label="Note">
+          <data type="string"/>
+        </attribute>
+        <attribute name="xxx" rngui:label="XXX">
+          <data type="string"/>
+        </attribute>
+        <data type="string" rngui:label="Url"/>
+      </element>
+    </zeroOrMore>
+  </element>
+</element>

+ 9 - 0
cpee/js_libs/tests/rngtest3.xml

@@ -0,0 +1,9 @@
+<call>
+  <arguments>
+    <timeout>2</timeout>
+  </arguments>
+  <_attachments>
+    <_attachment label="a" xxx="1">b</_attachment>
+    <_attachment label="c" xxx="2">d</_attachment>
+  </_attachments>
+</call>

+ 59 - 0
cpee/js_libs/tests/rngtest4.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 4</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest4.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest4.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 19 - 0
cpee/js_libs/tests/rngtest4.rng

@@ -0,0 +1,19 @@
+<element rngui:version="1.2" name="call" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <element name="_workorders">
+    <zeroOrMore rngui:label="Create Work Order">
+      <element name='_workorder'>
+        <attribute name="label" rngui:label="Note">
+          <data type="string"/>
+        </attribute>
+        <attribute name="duration" rngui:label="Duration">
+          <data type="string"/>
+        </attribute>
+        <zeroOrMore rngui:label="Add Attachment">
+          <element name='_attachment' rngui:label='Attachment'>
+            <data type="string"/>
+          </element>
+        </zeroOrMore>
+      </element>
+    </zeroOrMore>
+  </element>
+</element>

+ 12 - 0
cpee/js_libs/tests/rngtest4.xml

@@ -0,0 +1,12 @@
+<call>
+  <_workorders>
+    <_workorder label="a" duration="b">
+      <_attachment>1</_attachment>
+      <_attachment>2</_attachment>
+    </_workorder>
+    <_workorder label="c" duration="d">
+      <_attachment>3</_attachment>
+      <_attachment>4</_attachment>
+    </_workorder>
+  </_workorders>
+</call>

+ 59 - 0
cpee/js_libs/tests/rngtest5.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 5</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest5.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest5.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 75 - 0
cpee/js_libs/tests/rngtest5.rng

@@ -0,0 +1,75 @@
+<element rngui:version="1.2" name="call" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <element name='parameters' rngui:header="Parameters">
+    <element name="label" rngui:label="Label">
+      <data type="string" rngui:label="Short description of the task"/>
+    </element>
+    <element name="method" rngui:label="Method">
+      <choice>
+        <value>:post</value>
+        <value>:get</value>
+        <value>:put</value>
+        <value>:delete</value>
+      </choice>
+    </element>
+    <element name="arguments" rngui:header="Arguments">
+      <element name="nc-program" rngui:label="NC Program">
+        <data type="string" rngui:label="Unique ID of the NC Program"/>
+      </element>
+      <element name="material-name" rngui:label="Material Name">
+        <data type="string" rngui:label="Name of the raw material"/>
+      </element>
+      <element name="material-pic" rngui:label="Material Picture">
+        <data type="string" rngui:label="Picture of the raw material"/>
+      </element>
+      <element name="result-pic" rngui:label="Result Picture">
+        <data type="string" rngui:label="Picture of the result"/>
+      </element>
+      <element name="comment" rngui:label="Comment">
+        <text rngui:wrap='true' rngui:label='Additional comments for the operator'/>
+      </element>
+      <element name="tools" rngui:header="Tools">
+        <zeroOrMore rngui:label="Add Tool">
+          <element name="tool">
+            <element name="place" rngui:label="Position">
+              <data type="integer" rngui:label="Position in Tool Magazine"/>
+            </element>
+            <element name="tool-name" rngui:label="Tool">
+              <data type="string" rngui:label="Name of Tool"/>
+            </element>
+            <element name="tool-holder" rngui:label="Holder">
+              <data type="string" rngui:label="Name of Tool Holder"/>
+            </element>
+            <element name="tool-orientation" rngui:label="Orientation">
+              <data type="string" rngui:label="Orientation in Tool Holder"/>
+            </element>
+            <element name="corrections" rngui:header="Corrections">
+              <zeroOrMore rngui:label="Add Correction">
+                <element name="correction">
+                  <attribute name="length-x" rngui:label="Length X">
+                    <data type="float"/>
+                  </attribute>
+                  <attribute name="length-z" rngui:label="Length Y">
+                    <data type="float"/>
+                  </attribute>
+                  <attribute name="radius" rngui:label="Radius">
+                    <data type="float"/>
+                  </attribute>
+                </element>
+              </zeroOrMore>
+            </element>
+            <element name="attachments" rngui:header="Attachments">
+              <zeroOrMore rngui:label="Add Attachment">
+                <element name="attachment" rngui:label="URL">
+                  <attribute name="label" rngui:label="Label">
+                    <data type="string" rngui:label="Label"/>
+                  </attribute>
+                  <data type="string" rngui:label="URL"/>
+                </element>
+              </zeroOrMore>
+            </element>
+          </element>
+        </zeroOrMore>
+      </element>
+    </element>
+  </element>
+</element>

+ 40 - 0
cpee/js_libs/tests/rngtest5.xml

@@ -0,0 +1,40 @@
+<call>
+  <parameters>
+    <label></label>
+    <method>:post</method>
+    <arguments>
+      <nc-program>Kuli</nc-program>
+      <material-name>3</material-name>
+      <material-pic>http://centurio.work/customers/prime/part.jpg</material-pic>
+      <result-pic>http://centurio.work/customers/prime/result.jpg</result-pic>
+      <comment>Hallo</comment>
+      <tools>
+        <tool>
+          <place>1</place>
+          <tool-name>Schrupper (500)</tool-name>
+          <tool-holder>x3</tool-holder>
+          <tool-orientation>gegenspindel axial</tool-orientation>
+          <corrections>
+            <correction length-x="0" length-z="0" radius="70"/>
+            <correction length-x="1" length-z="1" radius="60"/>
+          </corrections>
+          <attachments>
+            <attachment label="Bla">http://centurio.work/customers/prime/attachment1.jpg</attachment>
+          </attachments>
+        </tool>
+        <tool>
+          <place>2</place>
+          <tool-name>Schaftfräser d6</tool-name>
+          <tool-holder>SK45</tool-holder>
+          <tool-orientation>-</tool-orientation>
+          <corrections>
+            <correction length-x="2" length-z="1" radius="2"/>
+          </corrections>
+          <attachments>
+            <attachment label="Tool">https://centurio.work/customers/prime/schaftfraeser.jpg</attachment>
+          </attachments>
+        </tool>
+      </tools>
+    </arguments>
+  </parameters>
+</call>

+ 59 - 0
cpee/js_libs/tests/rngtest6.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 6</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest6.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest6.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 24 - 0
cpee/js_libs/tests/rngtest6.rng

@@ -0,0 +1,24 @@
+<element rngui:version="1.2" rngui:header="Arguments" name="arguments" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <element name="behavior" rngui:label="Mode">
+    <choice>
+      <value>wait_running</value>
+      <value>fork_running</value>
+      <value>wait_ready</value>
+      <value>fork_ready</value>
+    </choice>
+  </element>
+  <element name="url" rngui:label="Process">
+    <data type="string" rngui:label="Link to centurio.work testset"/>
+  </element>
+  <element name="date" rngui:label="Due Date">
+    <data type="date" rngui:label="Due Date"/>
+  </element>
+  <element name="init" rngui:header="Initialize">
+    <zeroOrMore rngui:label="New Argument Pair">
+      <element rngui:label='Name'>
+        <anyName/>
+        <data type="string" rngui:label="Value"/>
+      </element>
+    </zeroOrMore>
+  </element>
+</element>

+ 6 - 0
cpee/js_libs/tests/rngtest6.xml

@@ -0,0 +1,6 @@
+<arguments>
+  <behavior>wait_runnig</behavior>
+  <url>3</url>
+  <date/>
+  <init/>
+</arguments>

+ 59 - 0
cpee/js_libs/tests/rngtest8.html

@@ -0,0 +1,59 @@
+<!--
+  This file is part of RelaxNGui.
+
+  RelaxNGui is free software: you can redistribute it and/or modify it under
+  the terms of the GNU General Public License as published by the Free Software
+  Foundation, either version 3 of the License, or (at your option) any later
+  version.
+
+  RelaxNGui is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  RelaxNGui (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>RelaxNGui Test 8</title>
+
+    <!-- libs, do not modify -->
+    <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
+    <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
+    <link rel="stylesheet"        href="/js_libs/relaxngui.css" type="text/css"/>
+    <script type="text/javascript" src="/js_libs/util.js"></script>
+    <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
+
+    <!-- custom stuff, play arround  -->
+
+    <script type="text/javascript">
+      $("body").ready(function(){
+        $.ajax({
+          type: "GET",
+          url: "rngtest8.rng",
+          success: function(rng){
+            $.ajax({
+              type: "GET",
+              url: "rngtest8.xml",
+              success: function(data){
+                var rngui = new RelaxNGui(rng,$('#show'));
+                rngui.content(data);
+                $('#saveall').on('click',function(){
+                  console.log($(rngui.save()).serializePrettyXML());
+                });
+              }
+            });
+          }
+        });
+      });
+    </script>
+  </head>
+  <body>
+    <div id="show"></div>
+    <button id='saveall'>save it all to console</button>
+  </body>
+</html>

+ 13 - 0
cpee/js_libs/tests/rngtest8.rng

@@ -0,0 +1,13 @@
+<element rngui:version="1.2" name="parallel" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org">
+  <attribute name="wait" rngui:label="Wait" rngui:default="-1" rngui:hint="-1 to wait for all branches.">
+    <data type="integer"/>
+  </attribute>
+  <element name="parallel_branch">
+    <attribute name="pass"><data type="string"/></attribute>
+    <attribute name="local"><data type="string"/></attribute>
+  </element>
+  <element name="parallel_branch">
+    <attribute name="pass"><data type="string"/></attribute>
+    <attribute name="local"><data type="string"/></attribute>
+  </element>
+</element>

+ 2 - 0
cpee/js_libs/tests/rngtest8.xml

@@ -0,0 +1,2 @@
+<choose mode="exclusive"/>
+

+ 301 - 0
cpee/js_libs/ui.css

@@ -0,0 +1,301 @@
+/*
+  This file is part of CPEE.
+
+  CPEE is free software: you can redistribute it and/or modify it under the terms
+  of the GNU General Public License as published by the Free Software Foundation,
+  either version 3 of the License, or (at your option) any later version.
+
+  CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  CPEE (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+*/
+
+:root {
+  --x-ui-border-color: #a1a1a1;
+  --x-ui-outside-color: #ffffff;
+  --x-ui-background-color: #ffffff;
+  --x-ui-light-text-color: #333;
+  --x-ui-light-back-color: #e8e8e8;
+  --x-ui-link-color: #425d73;
+}
+
+body {
+  font-family: sans-serif;
+  font-size: 1em;
+}
+
+*[is=x-ui] {
+  font-family: sans-serif,Arial,Verdana,Helvetica;
+  font-size: 0.85em;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background-color: var(--x-ui-outside-color);
+  padding:0;
+  margin:0;
+  color: var(--x-ui-light-text-color);
+  overflow: hidden;
+}
+
+/* Browser Bug, set textarea explicitly */
+*[is=x-ui] textarea, input, select, button {
+  font-family: Verdana, Helvetica, sans-serif;
+  font-size: 1em;
+  resize: none;
+}
+
+*[is=x-ui] button {
+  padding: .1em .2em;
+  border: 1pt solid var(--x-ui-border-color);
+  border-radius: 0.2em;
+  margin: 0;
+  font-size: 0.9em;
+  background: var(--x-ui-light-back-color);
+  background: -webkit-gradient(linear, left top, left bottom, from(white), to(var(--x-ui-light-back-color)));
+  background: -moz-linear-gradient(top, white, var(--x-ui-light-back-color));
+}
+*[is=x-ui] button::-moz-focus-inner {
+  border: 0 none;
+  padding: 0;
+  margin: 0;
+}
+*[is=x-ui] button.highlight {
+  background: -webkit-gradient(linear, left top, left bottom, from(white), to(Highlight));
+  background: -moz-linear-gradient(top, white, Highlight);
+}
+
+*[is=x-ui] input { font-family: sans-serif; font-size: 1em; }
+*[is=x-ui] input::-webkit-input-placeholder { color: red; }
+*[is=x-ui] input:-moz-placeholder { color: red; }
+
+*[is=x-ui] a:link    { color:var(--x-ui-link-color); text-decoration:none; }
+*[is=x-ui] a:visited { color:var(--x-ui-link-color); text-decoration:none; }
+*[is=x-ui] a:hover   { color:var(--x-ui-light-text-color); text-decoration:underline; }
+*[is=x-ui] a:active  { color:var(--x-ui-light-text-color); text-decoration:underline; }
+
+*[is=x-ui] ui-tabbed {
+  background-color: var(--x-ui-outside-color);
+  min-height: -webkit-min-content;
+  min-height: -moz-min-content;
+  min-height: min-content;
+  margin-left: 0.5em;
+  margin-right: 0.5em;
+}
+*[is=x-ui] ui-rest {
+  display: flex;
+  background-color: var(--x-ui-background-color);
+  align-items: stretch;
+  flex-direction: column;
+  padding: 0;
+  margin: 0;
+  flex: 1 1 auto;
+}
+
+*[is=x-ui] ui-tabbed.off {
+  border-bottom: 0.2em solid var(--x-ui-border-color);
+  border-radius: 0;
+}
+*[is=x-ui] ui-tabbed.off > ui-content {
+  display: none;
+}
+*[is=x-ui] ui-tabbed.off > ui-tabbar > ui-behind {
+  display: none;
+}
+
+*[is=x-ui] ui-tabbar {
+  background-color: var(--x-ui-outside-color);
+  display: flex;
+  align-items: stretch;
+  flex-direction: row;
+  padding: 0;
+  margin: 0;
+  padding-top: 0.5em;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+*[is=x-ui] ui-tabbed > ui-tabbar > ui-tab.switch {
+  background-color: var(--x-ui-light-back-color);
+}
+*[is=x-ui] ui-tabbed > ui-tabbar > ui-tab.switch:after {
+  content: "▽";
+  font-weight: bold;
+  vertical-align:top;
+  color: var(--x-ui-light-text-color);
+}
+*[is=x-ui] ui-tabbed.off > ui-tabbar > ui-tab.switch:after {
+  content: "▶";
+  font-weight: bold;
+  color: var(--x-ui-light-text-color);
+  vertical-align:top;
+}
+
+*[is=x-ui] ui-tabbar > ui-tab {
+  font-size: 1.4em;
+  font-weight: bold;
+  white-space: nowrap;
+
+  cursor: pointer;
+  padding: 0.3em 0.5em;
+  border: 1pt solid var(--x-ui-border-color);
+  border-bottom: 1pt solid var(--x-ui-background-color);
+  border-radius: 0.7em;
+  border-bottom-left-radius: 0em;
+  border-bottom-right-radius: 0em;
+  background: var(--x-ui-background-color);
+}
+*[is=x-ui] ui-tabbar > ui-tab.inactive, ui-tabbed > ui-tabbar > ui-tab.switch {
+  border: 1pt solid var(--x-ui-border-color);
+  border-radius: 0.7em;
+  border-bottom-left-radius: 0em;
+  border-bottom-right-radius: 0em;
+}
+
+*[is=x-ui] ui-tabbar > ui-behind {
+  flex: 1 1 auto;
+  vertical-align:bottom;
+  padding: 0;
+  padding-top: 0.9em;
+  border-bottom: 1pt solid var(--x-ui-border-color);
+  border-radius: 0.7em;
+  border-bottom-left-radius: 0em;
+  border-bottom-right-radius: 0em;
+  text-align:right;
+  white-space: nowrap;
+}
+*[is=x-ui] ui-rest > ui-tabbar > ui-behind {
+  padding-right: 0.5em;
+}
+
+*[is=x-ui] ui-rest > ui-tabbar > ui-before {
+  border-bottom: 1pt solid var(--x-ui-border-color);
+  padding-left:0.5em;
+}
+
+*[is=x-ui] ui-content {
+  background-color: var(--x-ui-background-color);
+  padding: 1em;
+  margin: 0;
+  border-bottom: 1pt solid var(--x-ui-border-color);
+  border-left: 1pt solid var(--x-ui-border-color);
+  border-right: 1pt solid var(--x-ui-border-color);
+  border-bottom-left-radius: 1em;
+  border-bottom-right-radius: 1em;
+}
+
+*[is=x-ui] ui-rest > ui-content {
+  padding: 0;
+  margin: 0;
+  border-radius: 0;
+  border: 0 none;
+
+  display: flex;
+  height: 0;
+  flex-direction: row;
+  flex: 1 1 auto;
+}
+
+*[is=x-ui] ui-rest > ui-content > ui-area {
+  flex: 1 1 0%;
+  overflow-x: auto;
+  overflow-y: scroll;
+}
+
+*[is=x-ui] ui-rest > ui-content > ui-resizehandle {
+  width: 0em;
+}
+*[is=x-ui] ui-rest > ui-content > ui-resizehandle + ui-area > ui-tabbed {
+  margin-left: 1.5em;
+}
+*[is=x-ui] ui-rest > ui-content > ui-resizehandle + ui-area > ui-rest > ui-tabbar > ui-before {
+  padding-left: 1.5em;
+}
+
+*[is=x-ui] ui-close {
+  margin-left: 0.5em;
+}
+
+*[is=x-ui] ui-rest > ui-content > ui-resizehandle::before {
+  display: block;
+  position: absolute;
+  color: var(--x-ui-border-color);
+  white-space:nowrap;
+  cursor: ew-resize;
+  -webkit-transform: rotate(90deg);
+  -webkit-transform-origin: 0% 0%;
+  -moz-transform: rotate(90deg);
+  -moz-transform-origin: left top;
+  margin-left: 1.4em;
+  margin-top: 0.2em;
+  content: attr(data-label);
+}
+
+*[is=x-ui] ui-content > ui-area {
+  margin: 0;
+  padding: 0;
+}
+
+*[is=x-ui] > ui-resizehandle {
+  color: var(--x-ui-border-color);
+  white-space:nowrap;
+  z-index: 99999;
+  cursor: s-resize;
+  text-align: right;
+  margin-top: 0.2em;
+  margin-right: 0.5em;
+}
+
+*[is=x-ui] ui-tabbed, ui-content, ui-area { display: block; }
+*[is=x-ui] ui-content > ui-area.inactive, ui-content > ui-resizehandle.inactive, ui-rest > ui-content > ui-resizehandle.inactive { display: none }
+
+*[is=x-ui] ui-content > ui-area .x-ui-layout {
+  width: 100%;
+  border-collapse:collapse;
+  border-spacing:0;
+  border: 0 none;
+  padding:0;
+  margin:0;
+}
+*[is=x-ui] ui-rest > ui-content > ui-area .x-ui-layout {
+  border:1em solid var(--x-ui-background-color);
+  box-sizing:border-box;
+}
+*[is=x-ui] ui-content > ui-area .x-ui-layout td {
+  border:0 none;
+  padding:0;
+  margin:0;
+}
+*[is=x-ui] ui-content > ui-area .x-ui-layout tr {
+  border:0 none;
+  padding:0;
+  margin:0;
+}
+*[is=x-ui] ui-content > ui-area .x-ui-compact {
+  border-collapse:collapse;
+  border-spacing:0;
+  border:0 none;
+  padding:0;
+  margin:0;
+}
+
+*[is=x-ui] ui-content > ui-area .x-ui-compact td {
+  border:0 none;
+  padding:0;
+  margin:0;
+}
+*[is=x-ui] ui-content > ui-area .x-ui-compact tr {
+  border:0 none;
+  padding:0;
+  margin:0;
+}
+*[is=x-ui] ui-content > ui-area .x-ui-layout .fixed { white-space:nowrap; }
+*[is=x-ui] ui-content > ui-area .x-ui-layout .top { vertical-align: top; }
+
+*[is=x-ui] .hidden {
+  display: none;
+}

+ 168 - 0
cpee/js_libs/ui.html

@@ -0,0 +1,168 @@
+<!--
+  This file is part of CPEE.
+
+  CPEE is free software: you can redistribute it and/or modify it under the terms
+  of the GNU General Public License as published by the Free Software Foundation,
+  either version 3 of the License, or (at your option) any later version.
+
+  CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  CPEE (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>UI Test</title>
+
+    <!-- libs, do not modify. When local than load local libs. -->
+    <script type="text/javascript">
+      if ((document.location.host == 'localhost') && (document.location.protocol == 'http:')) {
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/jquery.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/jquery.browser.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/jquery.svg.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/jquery.svgdom.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/vkbeautify.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/util.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/printf.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/strftime.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/parsequery.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/underscore.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/jquery.caret.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/jquery.cookie.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/relaxngui.js">\x3C/script>');
+
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/ui.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://localhost/js_libs/custommenu.js">\x3C/script>');
+
+        document.write('<link rel="stylesheet" href="http://localhost/js_libs/custommenu.css" type="text/css"/>');
+        document.write('<link rel="stylesheet" href="http://localhost/js_libs/ui.css" type="text/css"/>');
+
+        document.write('<link rel="stylesheet" href="http://localhost/js_libs/relaxngui.css" type="text/css"/>');
+      } else if ((document.location.host == 'localhost') && (document.location.protocol == 'https:')) {
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/jquery.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/jquery.browser.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/jquery.svg.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/jquery.svgdom.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/vkbeautify.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/util.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/printf.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/strftime.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/parsequery.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/underscore.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/jquery.caret.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/jquery.cookie.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/relaxngui.js">\x3C/script>');
+
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/ui.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="https://localhost/js_libs/custommenu.js">\x3C/script>');
+
+        document.write('<link rel="stylesheet" href="https://localhost/js_libs/custommenu.css" type="text/css"/>');
+        document.write('<link rel="stylesheet" href="https://localhost/js_libs/ui.css" type="text/css"/>');
+
+        document.write('<link rel="stylesheet" href="https://localhost/js_libs/relaxngui.css" type="text/css"/>');
+      } else {
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/jquery.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/jquery.browser.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/jquery.svg.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/jquery.svgdom.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/vkbeautify.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/util.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/printf.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/strftime.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/parsequery.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/underscore.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/jquery.caret.min.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/jquery.cookie.js">\x3C/script>');
+
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/relaxngui.js">\x3C/script>');
+
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/ui.js">\x3C/script>');
+        document.write('<script type="text/javascript" src="http://gruppe.wst.univie.ac.at/js_libs/custommenu.js">\x3C/script>');
+
+        document.write('<link rel="stylesheet" href="http://gruppe.wst.univie.ac.at/js_libs/custommenu.css" type="text/css"/>');
+        document.write('<link rel="stylesheet" href="http://gruppe.wst.univie.ac.at/js_libs/ui.css" type="text/css"/>');
+
+        document.write('<link rel="stylesheet" href="http://gruppe.wst.univie.ac.at/js_libs/relaxngui.css" type="text/css"/>');
+      }
+    </script>
+  </head>
+  <body data-defaultport="9298" data-theme-base="themes" is="x-ui">
+    <ui-rest id="main">
+      <!--ui-tabbar>
+        <ui-before                                                 ></ui-before>
+        <ui-tab class=""         data-tab="details" id="tabdetails">Graph</ui-tab>
+        <ui-behind                                                 ></ui-behind>
+      </ui-tabbar-->
+      <ui-content>
+        <ui-area data-belongs-to-tab="details" id='graphcolumn'>
+        </ui-area>
+        <ui-resizehandle data-belongs-to-tab="details" data-label="drag to resize"></ui-resizehandle>
+        <ui-area data-belongs-to-tab="details" id="detailcolumn">
+
+          <ui-tabbed id="instance">
+            <ui-tabbar>
+              <ui-tab class="switch"                                                ></ui-tab>
+              <ui-tab class=""                data-tab="new"       id="tabnew"      >New</ui-tab>
+              <ui-tab class="inactive"        data-tab="instance"  id="tabinstance" >Instance</ui-tab>
+              <ui-tab class="inactive"        data-tab="execution" id="tabexecution">Execution</ui-tab>
+              <ui-behind                                                            ><a id='current-instance'></a><a id='current-instance-properties'></a><a id='current-instance-subscriptions'></a><a id='current-instance-callbacks'></a></ui-behind>
+            </ui-tabbar>
+            <ui-content>
+              <ui-area data-belongs-to-tab="new" id="areanew"> <!--{{{-->
+              </ui-area> <!--}}}-->
+              <ui-area data-belongs-to-tab="instance" id="areainstance" class="inactive"> <!--{{{-->
+              </ui-area> <!--}}}-->
+              <ui-area data-belongs-to-tab="execution" id="areaexecution" class='inactive'> <!--{{{-->
+              </ui-area> <!--}}}-->
+            </ui-content>
+          </ui-tabbed>
+          <!--ui-resizehandle>drag to resize</ui-resizehandle-->
+
+          <ui-tabbed id='parameters'>
+            <ui-tabbar>
+              <ui-tab class="switch"                                               ></ui-tab>
+              <ui-tab class=""         data-tab="dataelements" id="tabdataelements">Data Elements</ui-tab>
+              <ui-tab class="inactive" data-tab="endpoints"    id="tabendpoints"   >Endpoints</ui-tab>
+              <ui-tab class="inactive" data-tab="attributes"   id="tabattributes"  >Attributes</ui-tab>
+              <ui-behind                                                           ><button title='add entry'>New</button></ui-behind>
+            </ui-tabbar>
+            <ui-content>
+              <ui-area data-belongs-to-tab="dataelements" id="areadataelements"> <!--{{{-->
+                <div id="dat_dataelements"></div>
+              </ui-area> <!--}}}-->
+              <ui-area data-belongs-to-tab="endpoints" id="areaendpoints" class="inactive"> <!--{{{-->
+                <table id="dat_endpoints"></table>
+              </ui-area> <!--}}}-->
+              <ui-area data-belongs-to-tab="attributes" id="areaattributes" class="inactive"> <!--{{{-->
+                <table id="dat_attributes"></table>
+              </ui-area> <!--}}}-->
+            </ui-content>
+          </ui-tabbed>
+
+          <ui-rest id="sub">
+            <ui-tabbar>
+              <ui-before                                                 ></ui-before>
+              <ui-tab class="" data-tab="dsl"     id="tabdsl"    >Description</ui-tab>
+              <ui-tab class="inactive" data-tab="log"     id="tablog"    >Log</ui-tab>
+              <ui-behind                                                 ></ui-behind>
+            </ui-tabbar>
+            <ui-content>
+              <ui-area data-belongs-to-tab="dsl" id="areadsl" class="inactive">
+              </ui-area>
+              <ui-area data-belongs-to-tab="log" id="arealog" class="inactive">
+              </ui-area> <!--}}}-->
+            </ui-content>
+          </ui-rest>
+
+        </ui-area>
+      </ui-content>
+    </ui-rest>
+
+  </body>
+</html>

+ 172 - 0
cpee/js_libs/ui.js

@@ -0,0 +1,172 @@
+/*
+  This file is part of CPEE.
+
+  CPEE is free software: you can redistribute it and/or modify it under the terms
+  of the GNU General Public License as published by the Free Software Foundation,
+  either version 3 of the License, or (at your option) any later version.
+
+  CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  CPEE (file COPYING in the main directory).  If not, see
+  <http://www.gnu.org/licenses/>.
+*/
+
+function ui_click_tab(moi) { // {{{
+  $(moi).trigger('click');
+} // }}}
+
+function ui_close_tab(moi){
+  var active = $(moi).parent().attr('data-tab');
+  var tabbed = $(moi).parent().parent().parent();
+  var is_inactive = $(moi).parent().hasClass('inactive');
+  $('*[data-tab=' + active + ']').remove();
+  $('*[data-belongs-to-tab=' + active + ']').remove();
+  if (!is_inactive)
+    ui_click_tab($('ui-tabbar ui-tab.default'));
+}
+
+function ui_add_close(moi) {
+  $(moi).append($('<ui-close>✖</ui-close>'));
+}
+
+function ui_empty_tab_contents(id) {
+  $('ui-content ui-area[data-belongs-to-tab=' + id + ']').empty();
+}
+
+function ui_add_tab(tabbed,title,id,closeable,additionalclasses) {
+  additionalclasses = typeof additionalclasses !== 'undefined' ? additionalclasses : '';
+  if ($('ui-tabbar ui-tab[data-tab=' + id + ']').length > 0) {
+    ui_activate_tab($('ui-tabbar ui-tab[data-tab=' + id + ']'));
+    return false;
+  } else {
+    var instab = $("<ui-tab class='inactive" + (closeable ? ' closeable' : '') + (additionalclasses == '' ? '' : ' ' + additionalclasses) + "' data-tab='" + id + "'>" + title + "</ui-tab>");
+    var insarea = $("<ui-area data-belongs-to-tab='" + id + "' class='inactive'></ui-area>");
+    $(tabbed).find('ui-behind').before(instab);
+    $(tabbed).find('ui-content').append(insarea);
+    ui_add_close($('ui-tabbar ui-tab[data-tab=' + id + ']'));
+    return true;
+  }
+}
+
+function ui_clone_tab(tabbar,original,title,id,closeable,additionalclasses) {
+  additionalclasses = typeof additionalclasses !== 'undefined' ? additionalclasses : '';
+  var instab = $("<ui-tab class='inactive" + (closeable ? ' closeable' : '') + (additionalclasses == '' ? '' : ' ' + additionalclasses) + "' data-tab='" + id + "' id='tab_" + id + "'>" + title + "</ui-tab>");
+  var insarea = original.clone();
+  insarea.attr("data-belongs-to-tab",id);
+  insarea.attr("class","inactive");
+  $(tabbar).find('ui-behind').before(instab);
+  $(tabbar).parent().append(insarea);
+  ui_add_close($('ui-tabbed ui-tab[data-tab=' + id + ']'));
+}
+
+(function($) { //{{{
+  $.fn.dragcolumn = function() {
+    var drag = $(this);
+    var prev = drag.prev();
+    var next = drag.next();
+
+    this.on("mousedown", function(e) {
+      drag.addClass('draggable');
+      $(document).one("mouseup", function(e) {
+        drag.removeClass('draggable');
+        e.preventDefault();
+      });
+      e.preventDefault();
+    });
+
+    $(document).on("mousemove", function(e) {
+      if (!drag.hasClass('draggable'))
+        return;
+
+      // Assume 50/50 split between prev and next then adjust to
+      // the next X for prev
+      var total = prev.outerWidth() + next.outerWidth();
+      var pos = e.pageX - prev.offset().left;
+      if (pos > total) {
+        pos = total;
+      }
+
+      var leftPercentage = pos / total;
+      var rightPercentage = 1 - leftPercentage;
+
+      prev.css('flex', leftPercentage.toString());
+      next.css('flex', rightPercentage.toString());
+
+      e.preventDefault();
+    });
+  }
+  $.fn.dragresize = function() {
+    var drag = $(this);
+    var prev = drag.prev();
+    var initpos = 0;
+    var initheight = $("ui-content",prev).height();
+
+    this.on("mousedown", function(e) {
+      drag.addClass('draggable');
+      initpos = e.pageY;
+      $(document).one("mouseup", function(e) {
+        drag.removeClass('draggable');
+        e.preventDefault();
+      });
+      e.preventDefault();
+    });
+
+    $(document).on("mousemove", function(e) {
+      if (!drag.hasClass('draggable'))
+        return;
+
+      var pos = initheight - (initpos - e.pageY);
+      if (pos < 0)
+        return;
+
+      $("ui-content",prev).css('height', pos.toString());
+
+      e.preventDefault();
+    });
+  }
+})(jQuery); //}}}
+
+function ui_activate_tab(moi) { // {{{
+  var active = $(moi).attr('data-tab');
+  var tabbed = $(moi).parent().parent();
+  var tabs = [];
+  $("ui-tabbar > ui-tab",tabbed).each(function(){
+    if (!$(this).attr('class').match(/switch/)) {
+      tabs.push($(this).attr('data-tab'));
+    }
+  });
+  $(".inactive",tabbed).removeClass("inactive");
+  $.each(tabs,function(a,b){
+    if (b != active) {
+      $("ui-tabbar ui-tab[data-tab=" + b + "]",tabbed).addClass("inactive");
+      $("ui-content *[data-belongs-to-tab=" + b + "]",tabbed).addClass("inactive");
+    }
+  });
+} // }}}
+function ui_toggle_vis_tab(moi) {// {{{
+  if ($(moi)[0].nodeName == 'UI-TABBED') {
+    var tabbed = $(moi);
+  }
+  if ($(moi)[0].nodeName == 'UI-TAB') {
+    var tabbed = $(moi).parent().parent();
+  }
+  if (tabbed) {
+    tabbed.toggleClass('off');
+  }
+}// }}}
+
+$(document).ready(function() {
+  if (!($.browser.name == "Firefox" && $.browser.version >= 20) && !($.browser.name == "Chrome" && $.browser.version >= 30)) {
+    $('body').children().remove();
+    $('body').append('Sorry, only Firefox >= 20.0 and Chrom(e|ium) >= 17 for now.');
+  }
+  $('ui-rest ui-content ui-resizehandle').dragcolumn();
+  $('*[is=x-ui] > ui-resizehandle').dragresize();
+  $(document).on('click','ui-tabbar ui-tab.switch',function(){ui_toggle_vis_tab(this);});
+  $(document).on('click','ui-tabbar ui-tab:not(.switch)',function(){ui_activate_tab(this);});
+  ui_add_close($('ui-tabbar ui-tab.closeable'));
+  $(document).on('click','ui-tabbar ui-tab.closeable ui-close',function(){ui_close_tab(this);});
+});

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 27 - 0
cpee/js_libs/underscore.min.js


+ 84 - 0
cpee/js_libs/util.js

@@ -0,0 +1,84 @@
+$B64 = function(str) {
+  return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
+    function toSolidBytes(match, p1) {
+      return String.fromCharCode('0x' + p1);
+  }));
+}
+
+$.fn.to_em_raw = function(settings){
+  settings = jQuery.extend({
+      scope: 'body'
+  }, settings);
+  var that = parseInt(this[0]||"0",10),
+      scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;">&nbsp;</div>').appendTo(settings.scope),
+      scopeVal = scopeTest.height();
+  scopeTest.remove();
+  return (that / scopeVal).toFixed(8);
+};
+$.fn.to_em = function(settings){
+  return $(this[0]).to_em_raw(settings) + 'em';
+};
+
+$.fn.get_val = function () {
+  if ($(this).is('input') || $(this).is('select') || $(this).is('textarea')) {
+    return $(this).val();
+  } else {
+    var ret = $(this).html().replace(/<div>/g,'').replace(/<\/div>/g,'\n').replace(/<br\/?>/g,'\n').replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&apos;/g,'\'').trim();
+    if (ret == '') $(this).empty();
+    return ret;
+  }
+};
+$.fn.set_val = function (val) {
+  if ($(this).is('input') || $(this).is('select') || $(this).is('textarea')) {
+    $(this).val(val);
+  } else {
+    $(this).text(val);
+  }
+};
+$.fn.serializePrettyXML = function () {
+  return vkbeautify.xml(this.serializeXML(),'  ');
+};
+
+$.fn.serializeXML = function () {
+  var out = '';
+  if (typeof XMLSerializer == 'function') {
+      var xs = new XMLSerializer();
+      this.each(function() {
+          out += xs.serializeToString(this);
+      });
+  } else if (this[0] && this[0].xml != 'undefined') {
+      this.each(function() {
+          out += this.xml;
+      });
+  }
+  return out;
+};
+$.fn.serializePrettyXML = function () {
+  return vkbeautify.xml(this.serializeXML(),'  ');
+};
+
+String.prototype.repeat = function(num) {
+  return new Array(num + 1).join(this);
+};
+
+String.prototype.unserialize = function() {
+  var data = this.split("&");
+  var ret = new Array();
+  $.each(data, function(){
+      var properties = this.split("=");
+      ret.push([properties[0], properties[1]]);
+  });
+  return ret;
+};
+
+$XR = function(xmlstr) {
+  if (typeof xmlstr == "string") {
+    return $.parseXML(xmlstr);
+  } else {
+    return $(xmlstr.ownerDocument || xmlstr);
+  }
+};
+
+$X = function(xmlstr) {
+  return $($.parseXML(xmlstr).documentElement);
+};

+ 358 - 0
cpee/js_libs/vkbeautify.0.99.00.beta.js

@@ -0,0 +1,358 @@
+/**
+* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
+*
+* Version - 0.99.00.beta
+* Copyright (c) 2012 Vadim Kiryukhin
+* vkiryukhin @ gmail.com
+* http://www.eslinstructor.net/vkbeautify/
+*
+* Dual licensed under the MIT and GPL licenses:
+*   http://www.opensource.org/licenses/mit-license.php
+*   http://www.gnu.org/licenses/gpl.html
+*
+*   Pretty print
+*
+*        vkbeautify.xml(text [,indent_pattern]);
+*        vkbeautify.json(text [,indent_pattern]);
+*        vkbeautify.css(text [,indent_pattern]);
+*        vkbeautify.sql(text [,indent_pattern]);
+*
+*        @text - String; text to beatufy;
+*        @indent_pattern - Integer | String;
+*                Integer:  number of white spaces;
+*                String:   character string to visualize indentation ( can also be a set of white spaces )
+*   Minify
+*
+*        vkbeautify.xmlmin(text [,preserve_comments]);
+*        vkbeautify.jsonmin(text);
+*        vkbeautify.cssmin(text [,preserve_comments]);
+*        vkbeautify.sqlmin(text);
+*
+*        @text - String; text to minify;
+*        @preserve_comments - Bool; [optional];
+*                Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
+*
+*   Examples:
+*        vkbeautify.xml(text); // pretty print XML
+*        vkbeautify.json(text, 4 ); // pretty print JSON
+*        vkbeautify.css(text, '. . . .'); // pretty print CSS
+*        vkbeautify.sql(text, '----'); // pretty print SQL
+*
+*        vkbeautify.xmlmin(text, true);// minify XML, preserve comments
+*        vkbeautify.jsonmin(text);// minify JSON
+*        vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
+*        vkbeautify.sqlmin(text);// minify SQL
+*
+*/
+
+(function() {
+
+function createShiftArr(step) {
+
+	var space = '    ';
+
+	if ( isNaN(parseInt(step)) ) {  // argument is string
+		space = step;
+	} else { // argument is integer
+		switch(step) {
+			case 1: space = ' '; break;
+			case 2: space = '  '; break;
+			case 3: space = '   '; break;
+			case 4: space = '    '; break;
+			case 5: space = '     '; break;
+			case 6: space = '      '; break;
+			case 7: space = '       '; break;
+			case 8: space = '        '; break;
+			case 9: space = '         '; break;
+			case 10: space = '          '; break;
+			case 11: space = '           '; break;
+			case 12: space = '            '; break;
+		}
+	}
+
+	var shift = ['\n']; // array of shifts
+	for(ix=0;ix<100;ix++){
+		shift.push(shift[ix]+space);
+	}
+	return shift;
+}
+
+function vkbeautify(){
+	this.step = '    '; // 4 spaces
+	this.shift = createShiftArr(this.step);
+};
+
+vkbeautify.prototype.xml = function(text,step) {
+
+	var ar = text.replace(/>\s{0,}</g,"><")
+				 .replace(/</g,"~::~<")
+				 .replace(/\s*xmlns\:/g,"~::~xmlns:")
+				 // .replace(/\s*xmlns\=/g,"~::~xmlns=")
+				 .split('~::~'),
+		len = ar.length,
+		inComment = false,
+		deep = 0,
+		str = '',
+		ix = 0,
+		shift = step ? createShiftArr(step) : this.shift;
+
+		for(ix=0;ix<len;ix++) {
+			// start comment or <![CDATA[...]]> or <!DOCTYPE //
+			if(ar[ix].search(/<!/) > -1) {
+				str += shift[deep]+ar[ix];
+				inComment = true;
+				// end comment  or <![CDATA[...]]> //
+				if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
+					inComment = false;
+				}
+			} else
+			// end comment  or <![CDATA[...]]> //
+			if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
+				str += ar[ix];
+				inComment = false;
+			} else
+			// <elm></elm> //
+			if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
+				/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
+				str += ar[ix];
+				if(!inComment) deep--;
+			} else
+			 // <elm> //
+			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
+				str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
+			} else
+			 // <elm>...</elm> //
+			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
+				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
+			} else
+			// </elm> //
+			if(ar[ix].search(/<\//) > -1) {
+				str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
+			} else
+			// <elm/> //
+			if(ar[ix].search(/\/>/) > -1 ) {
+				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
+			} else
+			// <? xml ... ?> //
+			if(ar[ix].search(/<\?/) > -1) {
+				str += shift[deep]+ar[ix];
+			} else
+			// xmlns //
+			if( ar[ix].search(/xmlns\:/) > -1  || ar[ix].search(/xmlns\=/) > -1) {
+				str += shift[deep]+ar[ix];
+			}
+
+			else {
+				str += ar[ix];
+			}
+		}
+
+	return  (str[0] == '\n') ? str.slice(1) : str;
+}
+
+vkbeautify.prototype.json = function(text,step) {
+
+	var step = step ? step : this.step;
+
+	if (typeof JSON === 'undefined' ) return text;
+
+	if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
+	if ( typeof text === "object" ) return JSON.stringify(text, null, step);
+
+	return text; // text is not string nor object
+}
+
+vkbeautify.prototype.css = function(text, step) {
+
+	var ar = text.replace(/\s{1,}/g,' ')
+				.replace(/\{/g,"{~::~")
+				.replace(/\}/g,"~::~}~::~")
+				.replace(/\;/g,";~::~")
+				.replace(/\/\*/g,"~::~/*")
+				.replace(/\*\//g,"*/~::~")
+				.replace(/~::~\s{0,}~::~/g,"~::~")
+				.split('~::~'),
+		len = ar.length,
+		deep = 0,
+		str = '',
+		ix = 0,
+		shift = step ? createShiftArr(step) : this.shift;
+
+		for(ix=0;ix<len;ix++) {
+
+			if( /\{/.exec(ar[ix]))  {
+				str += shift[deep++]+ar[ix];
+			} else
+			if( /\}/.exec(ar[ix]))  {
+				str += shift[--deep]+ar[ix];
+			} else
+			if( /\*\\/.exec(ar[ix]))  {
+				str += shift[deep]+ar[ix];
+			}
+			else {
+				str += shift[deep]+ar[ix];
+			}
+		}
+		return str.replace(/^\n{1,}/,'');
+}
+
+//----------------------------------------------------------------------------
+
+function isSubquery(str, parenthesisLevel) {
+	return  parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
+}
+
+function split_sql(str, tab) {
+
+	return str.replace(/\s{1,}/g," ")
+
+				.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
+				.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
+				.replace(/ CASE /ig,"~::~"+tab+"CASE ")
+				.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
+				.replace(/ END /ig,"~::~"+tab+"END ")
+				.replace(/ FROM /ig,"~::~FROM ")
+				.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
+				.replace(/ HAVING /ig,"~::~HAVING ")
+				//.replace(/ SET /ig," SET~::~")
+				.replace(/ IN /ig," IN ")
+
+				.replace(/ JOIN /ig,"~::~JOIN ")
+				.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
+				.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
+				.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
+				.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
+
+				.replace(/ ON /ig,"~::~"+tab+"ON ")
+				.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
+				.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
+				.replace(/ OVER /ig,"~::~"+tab+"OVER ")
+
+				.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
+				.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
+
+				.replace(/ THEN /ig," THEN~::~"+tab+"")
+				.replace(/ UNION /ig,"~::~UNION~::~")
+				.replace(/ USING /ig,"~::~USING ")
+				.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
+				.replace(/ WHERE /ig,"~::~WHERE ")
+				.replace(/ WITH /ig,"~::~WITH ")
+
+				//.replace(/\,\s{0,}\(/ig,",~::~( ")
+				//.replace(/\,/ig,",~::~"+tab+tab+"")
+
+				.replace(/ ALL /ig," ALL ")
+				.replace(/ AS /ig," AS ")
+				.replace(/ ASC /ig," ASC ")
+				.replace(/ DESC /ig," DESC ")
+				.replace(/ DISTINCT /ig," DISTINCT ")
+				.replace(/ EXISTS /ig," EXISTS ")
+				.replace(/ NOT /ig," NOT ")
+				.replace(/ NULL /ig," NULL ")
+				.replace(/ LIKE /ig," LIKE ")
+				.replace(/\s{0,}SELECT /ig,"SELECT ")
+				.replace(/\s{0,}UPDATE /ig,"UPDATE ")
+				.replace(/ SET /ig," SET ")
+
+				.replace(/~::~{1,}/g,"~::~")
+				.split('~::~');
+}
+
+vkbeautify.prototype.sql = function(text,step) {
+
+	var ar_by_quote = text.replace(/\s{1,}/g," ")
+							.replace(/\'/ig,"~::~\'")
+							.split('~::~'),
+		len = ar_by_quote.length,
+		ar = [],
+		deep = 0,
+		tab = this.step,//+this.step,
+		inComment = true,
+		inQuote = false,
+		parenthesisLevel = 0,
+		str = '',
+		ix = 0,
+		shift = step ? createShiftArr(step) : this.shift;;
+
+		for(ix=0;ix<len;ix++) {
+			if(ix%2) {
+				ar = ar.concat(ar_by_quote[ix]);
+			} else {
+				ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
+			}
+		}
+
+		len = ar.length;
+		for(ix=0;ix<len;ix++) {
+
+			parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
+
+			if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix]))  {
+				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
+			}
+
+			if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix]))  {
+				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
+			}
+
+			if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix]))  {
+				deep++;
+				str += shift[deep]+ar[ix];
+			} else
+			if( /\'/.exec(ar[ix]) )  {
+				if(parenthesisLevel<1 && deep) {
+					deep--;
+				}
+				str += ar[ix];
+			}
+			else  {
+				str += shift[deep]+ar[ix];
+				if(parenthesisLevel<1 && deep) {
+					deep--;
+				}
+			}
+			var junk = 0;
+		}
+
+		str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
+		return str;
+}
+
+
+vkbeautify.prototype.xmlmin = function(text, preserveComments) {
+
+	var str = preserveComments ? text
+							   : text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
+									 .replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
+	return  str.replace(/>\s{0,}</g,"><");
+}
+
+vkbeautify.prototype.jsonmin = function(text) {
+
+	if (typeof JSON === 'undefined' ) return text;
+
+	return JSON.stringify(JSON.parse(text), null, 0);
+
+}
+
+vkbeautify.prototype.cssmin = function(text, preserveComments) {
+
+	var str = preserveComments ? text
+							   : text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
+
+	return str.replace(/\s{1,}/g,' ')
+			  .replace(/\{\s{1,}/g,"{")
+			  .replace(/\}\s{1,}/g,"}")
+			  .replace(/\;\s{1,}/g,";")
+			  .replace(/\/\*\s{1,}/g,"/*")
+			  .replace(/\*\/\s{1,}/g,"*/");
+}
+
+vkbeautify.prototype.sqlmin = function(text) {
+	return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
+}
+
+window.vkbeautify = new vkbeautify();
+
+})();
+

+ 358 - 0
cpee/js_libs/vkbeautify.js

@@ -0,0 +1,358 @@
+/**
+* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
+*
+* Version - 0.99.00.beta
+* Copyright (c) 2012 Vadim Kiryukhin
+* vkiryukhin @ gmail.com
+* http://www.eslinstructor.net/vkbeautify/
+*
+* Dual licensed under the MIT and GPL licenses:
+*   http://www.opensource.org/licenses/mit-license.php
+*   http://www.gnu.org/licenses/gpl.html
+*
+*   Pretty print
+*
+*        vkbeautify.xml(text [,indent_pattern]);
+*        vkbeautify.json(text [,indent_pattern]);
+*        vkbeautify.css(text [,indent_pattern]);
+*        vkbeautify.sql(text [,indent_pattern]);
+*
+*        @text - String; text to beatufy;
+*        @indent_pattern - Integer | String;
+*                Integer:  number of white spaces;
+*                String:   character string to visualize indentation ( can also be a set of white spaces )
+*   Minify
+*
+*        vkbeautify.xmlmin(text [,preserve_comments]);
+*        vkbeautify.jsonmin(text);
+*        vkbeautify.cssmin(text [,preserve_comments]);
+*        vkbeautify.sqlmin(text);
+*
+*        @text - String; text to minify;
+*        @preserve_comments - Bool; [optional];
+*                Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
+*
+*   Examples:
+*        vkbeautify.xml(text); // pretty print XML
+*        vkbeautify.json(text, 4 ); // pretty print JSON
+*        vkbeautify.css(text, '. . . .'); // pretty print CSS
+*        vkbeautify.sql(text, '----'); // pretty print SQL
+*
+*        vkbeautify.xmlmin(text, true);// minify XML, preserve comments
+*        vkbeautify.jsonmin(text);// minify JSON
+*        vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
+*        vkbeautify.sqlmin(text);// minify SQL
+*
+*/
+
+(function() {
+
+function createShiftArr(step) {
+
+	var space = '    ';
+
+	if ( isNaN(parseInt(step)) ) {  // argument is string
+		space = step;
+	} else { // argument is integer
+		switch(step) {
+			case 1: space = ' '; break;
+			case 2: space = '  '; break;
+			case 3: space = '   '; break;
+			case 4: space = '    '; break;
+			case 5: space = '     '; break;
+			case 6: space = '      '; break;
+			case 7: space = '       '; break;
+			case 8: space = '        '; break;
+			case 9: space = '         '; break;
+			case 10: space = '          '; break;
+			case 11: space = '           '; break;
+			case 12: space = '            '; break;
+		}
+	}
+
+	var shift = ['\n']; // array of shifts
+	for(ix=0;ix<100;ix++){
+		shift.push(shift[ix]+space);
+	}
+	return shift;
+}
+
+function vkbeautify(){
+	this.step = '    '; // 4 spaces
+	this.shift = createShiftArr(this.step);
+};
+
+vkbeautify.prototype.xml = function(text,step) {
+
+	var ar = text.replace(/>\s{0,}</g,"><")
+				 .replace(/</g,"~::~<")
+				 .replace(/\s*xmlns\:/g,"~::~xmlns:")
+				 // .replace(/\s*xmlns\=/g,"~::~xmlns=")
+				 .split('~::~'),
+		len = ar.length,
+		inComment = false,
+		deep = 0,
+		str = '',
+		ix = 0,
+		shift = step ? createShiftArr(step) : this.shift;
+
+		for(ix=0;ix<len;ix++) {
+			// start comment or <![CDATA[...]]> or <!DOCTYPE //
+			if(ar[ix].search(/<!/) > -1) {
+				str += shift[deep]+ar[ix];
+				inComment = true;
+				// end comment  or <![CDATA[...]]> //
+				if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
+					inComment = false;
+				}
+			} else
+			// end comment  or <![CDATA[...]]> //
+			if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
+				str += ar[ix];
+				inComment = false;
+			} else
+			// <elm></elm> //
+			if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
+				/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
+				str += ar[ix];
+				if(!inComment) deep--;
+			} else
+			 // <elm> //
+			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
+				str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
+			} else
+			 // <elm>...</elm> //
+			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
+				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
+			} else
+			// </elm> //
+			if(ar[ix].search(/<\//) > -1) {
+				str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
+			} else
+			// <elm/> //
+			if(ar[ix].search(/\/>/) > -1 ) {
+				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
+			} else
+			// <? xml ... ?> //
+			if(ar[ix].search(/<\?/) > -1) {
+				str += shift[deep]+ar[ix];
+			} else
+			// xmlns //
+			if( ar[ix].search(/xmlns\:/) > -1  || ar[ix].search(/xmlns\=/) > -1) {
+				str += shift[deep]+ar[ix];
+			}
+
+			else {
+				str += ar[ix];
+			}
+		}
+
+	return  (str[0] == '\n') ? str.slice(1) : str;
+}
+
+vkbeautify.prototype.json = function(text,step) {
+
+	var step = step ? step : this.step;
+
+	if (typeof JSON === 'undefined' ) return text;
+
+	if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
+	if ( typeof text === "object" ) return JSON.stringify(text, null, step);
+
+	return text; // text is not string nor object
+}
+
+vkbeautify.prototype.css = function(text, step) {
+
+	var ar = text.replace(/\s{1,}/g,' ')
+				.replace(/\{/g,"{~::~")
+				.replace(/\}/g,"~::~}~::~")
+				.replace(/\;/g,";~::~")
+				.replace(/\/\*/g,"~::~/*")
+				.replace(/\*\//g,"*/~::~")
+				.replace(/~::~\s{0,}~::~/g,"~::~")
+				.split('~::~'),
+		len = ar.length,
+		deep = 0,
+		str = '',
+		ix = 0,
+		shift = step ? createShiftArr(step) : this.shift;
+
+		for(ix=0;ix<len;ix++) {
+
+			if( /\{/.exec(ar[ix]))  {
+				str += shift[deep++]+ar[ix];
+			} else
+			if( /\}/.exec(ar[ix]))  {
+				str += shift[--deep]+ar[ix];
+			} else
+			if( /\*\\/.exec(ar[ix]))  {
+				str += shift[deep]+ar[ix];
+			}
+			else {
+				str += shift[deep]+ar[ix];
+			}
+		}
+		return str.replace(/^\n{1,}/,'');
+}
+
+//----------------------------------------------------------------------------
+
+function isSubquery(str, parenthesisLevel) {
+	return  parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
+}
+
+function split_sql(str, tab) {
+
+	return str.replace(/\s{1,}/g," ")
+
+				.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
+				.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
+				.replace(/ CASE /ig,"~::~"+tab+"CASE ")
+				.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
+				.replace(/ END /ig,"~::~"+tab+"END ")
+				.replace(/ FROM /ig,"~::~FROM ")
+				.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
+				.replace(/ HAVING /ig,"~::~HAVING ")
+				//.replace(/ SET /ig," SET~::~")
+				.replace(/ IN /ig," IN ")
+
+				.replace(/ JOIN /ig,"~::~JOIN ")
+				.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
+				.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
+				.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
+				.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
+
+				.replace(/ ON /ig,"~::~"+tab+"ON ")
+				.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
+				.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
+				.replace(/ OVER /ig,"~::~"+tab+"OVER ")
+
+				.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
+				.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
+
+				.replace(/ THEN /ig," THEN~::~"+tab+"")
+				.replace(/ UNION /ig,"~::~UNION~::~")
+				.replace(/ USING /ig,"~::~USING ")
+				.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
+				.replace(/ WHERE /ig,"~::~WHERE ")
+				.replace(/ WITH /ig,"~::~WITH ")
+
+				//.replace(/\,\s{0,}\(/ig,",~::~( ")
+				//.replace(/\,/ig,",~::~"+tab+tab+"")
+
+				.replace(/ ALL /ig," ALL ")
+				.replace(/ AS /ig," AS ")
+				.replace(/ ASC /ig," ASC ")
+				.replace(/ DESC /ig," DESC ")
+				.replace(/ DISTINCT /ig," DISTINCT ")
+				.replace(/ EXISTS /ig," EXISTS ")
+				.replace(/ NOT /ig," NOT ")
+				.replace(/ NULL /ig," NULL ")
+				.replace(/ LIKE /ig," LIKE ")
+				.replace(/\s{0,}SELECT /ig,"SELECT ")
+				.replace(/\s{0,}UPDATE /ig,"UPDATE ")
+				.replace(/ SET /ig," SET ")
+
+				.replace(/~::~{1,}/g,"~::~")
+				.split('~::~');
+}
+
+vkbeautify.prototype.sql = function(text,step) {
+
+	var ar_by_quote = text.replace(/\s{1,}/g," ")
+							.replace(/\'/ig,"~::~\'")
+							.split('~::~'),
+		len = ar_by_quote.length,
+		ar = [],
+		deep = 0,
+		tab = this.step,//+this.step,
+		inComment = true,
+		inQuote = false,
+		parenthesisLevel = 0,
+		str = '',
+		ix = 0,
+		shift = step ? createShiftArr(step) : this.shift;;
+
+		for(ix=0;ix<len;ix++) {
+			if(ix%2) {
+				ar = ar.concat(ar_by_quote[ix]);
+			} else {
+				ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
+			}
+		}
+
+		len = ar.length;
+		for(ix=0;ix<len;ix++) {
+
+			parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
+
+			if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix]))  {
+				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
+			}
+
+			if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix]))  {
+				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
+			}
+
+			if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix]))  {
+				deep++;
+				str += shift[deep]+ar[ix];
+			} else
+			if( /\'/.exec(ar[ix]) )  {
+				if(parenthesisLevel<1 && deep) {
+					deep--;
+				}
+				str += ar[ix];
+			}
+			else  {
+				str += shift[deep]+ar[ix];
+				if(parenthesisLevel<1 && deep) {
+					deep--;
+				}
+			}
+			var junk = 0;
+		}
+
+		str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
+		return str;
+}
+
+
+vkbeautify.prototype.xmlmin = function(text, preserveComments) {
+
+	var str = preserveComments ? text
+							   : text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
+									 .replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
+	return  str.replace(/>\s{0,}</g,"><");
+}
+
+vkbeautify.prototype.jsonmin = function(text) {
+
+	if (typeof JSON === 'undefined' ) return text;
+
+	return JSON.stringify(JSON.parse(text), null, 0);
+
+}
+
+vkbeautify.prototype.cssmin = function(text, preserveComments) {
+
+	var str = preserveComments ? text
+							   : text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
+
+	return str.replace(/\s{1,}/g,' ')
+			  .replace(/\{\s{1,}/g,"{")
+			  .replace(/\}\s{1,}/g,"}")
+			  .replace(/\;\s{1,}/g,";")
+			  .replace(/\/\*\s{1,}/g,"/*")
+			  .replace(/\*\/\s{1,}/g,"*/");
+}
+
+vkbeautify.prototype.sqlmin = function(text) {
+	return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
+}
+
+window.vkbeautify = new vkbeautify();
+
+})();
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 196 - 0
cpee/js_libs/webcomponents.min.js


+ 9 - 9
docker-compose.yml

@@ -1,24 +1,24 @@
 version: '3'
 
 services:
+
   cpee:
-    image: "cpee:1.4.26"
-    network_mode: "host" # Temporary workaround for using localhost address  in process templates
+    build: ./cpee
+    network_mode: "host" # Enable using 'localhost' in process templates
     ports:
         - "8298:8298"
     volumes:
         - cpeeCockpit:/cpee-cockpit
-        - cpeeServer:/cpee-server
+
   nginx:
     image: "nginx:alpine"
     ports:
-        - "9111:80"
+        - "9090:80"
     volumes:
-        - cpeeCockpit:/usr/share/nginx/html/cockpit:ro
-          # Note, that the js libs had to be manually downloaded, 
-          # they aren't part of the cpee gem.
-        - /var/www/html/js_libs:/usr/share/nginx/html/js_libs:ro
+        - cpeeCockpit:/usr/share/nginx/html/cpee-cockpit:ro
+        - ./cpee/js_libs:/usr/share/nginx/html/js_libs:ro
+
 volumes:
     # System managed volumes
     cpeeCockpit:
-    cpeeServer:
+