diff --git a/thirdpartyjs/extjs/air/README.txt b/thirdpartyjs/extjs/air/README.txt
new file mode 100644
index 0000000..f5593d5
--- /dev/null
+++ b/thirdpartyjs/extjs/air/README.txt
@@ -0,0 +1,8 @@
+The ext-air.js file should be included AFTER ext-all.js.
+
+The resources/ext-air.css file should be included AFTER ext-all.css.
+
+XTemplates must be loaded inline while the js file loads (not in an onready block) when used in the application sandbox. Take a look at samples/tasks/js/Templates.js for an example.
+
+For additional date formats other than the ones defined in src/ext-air-adapter.js, you will need to specify them inline similar to XTemplates using Date.precompileFormats(). For multiple formats, separate them with the | character.
+
diff --git a/thirdpartyjs/extjs/air/air.jsb b/thirdpartyjs/extjs/air/air.jsb
new file mode 100644
index 0000000..693c03c
--- /dev/null
+++ b/thirdpartyjs/extjs/air/air.jsb
@@ -0,0 +1,379 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/ext-air.js b/thirdpartyjs/extjs/air/ext-air.js
new file mode 100644
index 0000000..1d04d87
--- /dev/null
+++ b/thirdpartyjs/extjs/air/ext-air.js
@@ -0,0 +1,1655 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+
+Ext.namespace('Ext.air', 'Ext.sql');
+
+Ext.Template.prototype.compile = function() {
+ var fm = Ext.util.Format;
+ var useF = this.disableFormats !== true;
+
+ var prevOffset = 0;
+ var arr = [];
+ var tpl = this;
+ var fn = function(m, name, format, args, offset, s){
+ if (prevOffset != offset) {
+ var action = {type: 1, value: s.substr(prevOffset, offset - prevOffset)};
+ arr.push(action);
+ }
+ prevOffset = offset + m.length;
+ if(format && useF){
+ if (args) {
+ var re = /^\s*['"](.*)["']\s*$/;
+ args = args.split(/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/);
+ for(var i = 0, len = args.length; i < len; i++){
+ args[i] = args[i].replace(re, "$1");
+ }
+ args = [''].concat(args);
+ } else {
+ args = [''];
+ }
+ if(format.substr(0, 5) != "this."){
+ var action = {type: 3, value:name, format: fm[format], args: args, scope: fm};
+ arr.push(action);
+ }else{
+ var action = {type: 3, value:name, format:tpl[format.substr(5)], args:args, scope: tpl};
+ arr.push(action);
+ }
+ }else{
+ var action = {type: 2, value: name};
+ arr.push(action);
+ }
+ return m;
+ };
+
+ var s = this.html.replace(this.re, fn);
+ if (prevOffset != (s.length - 1)) {
+ var action = {type: 1, value: s.substr(prevOffset, s.length - prevOffset)};
+ arr.push(action);
+ }
+
+ this.compiled = function(values) {
+ function applyValues(el) {
+ switch (el.type) {
+ case 1:
+ return el.value;
+ case 2:
+ return (values[el.value] ? values[el.value] : '');
+ default:
+ el.args[0] = values[el.value];
+ return el.format.apply(el.scope, el.args);
+ }
+ }
+ return arr.map(applyValues).join('');
+ }
+ return this;
+};
+
+Ext.Template.prototype.call = function(fnName, value, allValues){
+ return this[fnName](value, allValues);
+}
+
+
+Ext.DomQuery = function(){
+ var cache = {}, simpleCache = {}, valueCache = {};
+ var nonSpace = /\S/;
+ var trimRe = /^\s+|\s+$/g;
+ var tplRe = /\{(\d+)\}/g;
+ var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
+ var tagTokenRe = /^(#)?([\w-\*]+)/;
+ var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
+
+ function child(p, index){
+ var i = 0;
+ var n = p.firstChild;
+ while(n){
+ if(n.nodeType == 1){
+ if(++i == index){
+ return n;
+ }
+ }
+ n = n.nextSibling;
+ }
+ return null;
+ };
+
+ function next(n){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ return n;
+ };
+
+ function prev(n){
+ while((n = n.previousSibling) && n.nodeType != 1);
+ return n;
+ };
+
+ function children(d){
+ var n = d.firstChild, ni = -1;
+ while(n){
+ var nx = n.nextSibling;
+ if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
+ d.removeChild(n);
+ }else{
+ n.nodeIndex = ++ni;
+ }
+ n = nx;
+ }
+ return this;
+ };
+
+ function byClassName(c, a, v){
+ if(!v){
+ return c;
+ }
+ var r = [], ri = -1, cn;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if((' '+ci.className+' ').indexOf(v) != -1){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ };
+
+ function attrValue(n, attr){
+ if(!n.tagName && typeof n.length != "undefined"){
+ n = n[0];
+ }
+ if(!n){
+ return null;
+ }
+ if(attr == "for"){
+ return n.htmlFor;
+ }
+ if(attr == "class" || attr == "className"){
+ return n.className;
+ }
+ return n.getAttribute(attr) || n[attr];
+
+ };
+
+ function getNodes(ns, mode, tagName){
+ var result = [], ri = -1, cs;
+ if(!ns){
+ return result;
+ }
+ tagName = tagName || "*";
+ if(typeof ns.getElementsByTagName != "undefined"){
+ ns = [ns];
+ }
+ if(!mode){
+ for(var i = 0, ni; ni = ns[i]; i++){
+ cs = ni.getElementsByTagName(tagName);
+ for(var j = 0, ci; ci = cs[j]; j++){
+ result[++ri] = ci;
+ }
+ }
+ }else if(mode == "/" || mode == ">"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, ni, cn; ni = ns[i]; i++){
+ cn = ni.children || ni.childNodes;
+ for(var j = 0, cj; cj = cn[j]; j++){
+ if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
+ result[++ri] = cj;
+ }
+ }
+ }
+ }else if(mode == "+"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, n; n = ns[i]; i++){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
+ result[++ri] = n;
+ }
+ }
+ }else if(mode == "~"){
+ for(var i = 0, n; n = ns[i]; i++){
+ while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
+ if(n){
+ result[++ri] = n;
+ }
+ }
+ }
+ return result;
+ };
+
+ function concat(a, b){
+ if(b.slice){
+ return a.concat(b);
+ }
+ for(var i = 0, l = b.length; i < l; i++){
+ a[a.length] = b[i];
+ }
+ return a;
+ }
+
+ function byTag(cs, tagName){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!tagName){
+ return cs;
+ }
+ var r = [], ri = -1;
+ tagName = tagName.toLowerCase();
+ for(var i = 0, ci; ci = cs[i]; i++){
+ if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ };
+
+ function byId(cs, attr, id){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!id){
+ return cs;
+ }
+ var r = [], ri = -1;
+ for(var i = 0,ci; ci = cs[i]; i++){
+ if(ci && ci.id == id){
+ r[++ri] = ci;
+ return r;
+ }
+ }
+ return r;
+ };
+
+ function byAttribute(cs, attr, value, op, custom){
+ var r = [], ri = -1, st = custom=="{";
+ var f = Ext.DomQuery.operators[op];
+ for(var i = 0, ci; ci = cs[i]; i++){
+ var a;
+ if(st){
+ a = Ext.DomQuery.getStyle(ci, attr);
+ }
+ else if(attr == "class" || attr == "className"){
+ a = ci.className;
+ }else if(attr == "for"){
+ a = ci.htmlFor;
+ }else if(attr == "href"){
+ a = ci.getAttribute("href", 2);
+ }else{
+ a = ci.getAttribute(attr);
+ }
+ if((f && f(a, value)) || (!f && a)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ };
+
+ function byPseudo(cs, name, value){
+ return Ext.DomQuery.pseudos[name](cs, value);
+ };
+
+
+
+
+ eval("var batch = 30803;");
+
+ var key = 30803;
+
+ function nodup(cs){
+ if(!cs){
+ return [];
+ }
+ var len = cs.length, c, i, r = cs, cj, ri = -1;
+ if(!len || typeof cs.nodeType != "undefined" || len == 1){
+ return cs;
+ }
+ var d = ++key;
+ cs[0]._nodup = d;
+ for(i = 1; c = cs[i]; i++){
+ if(c._nodup != d){
+ c._nodup = d;
+ }else{
+ r = [];
+ for(var j = 0; j < i; j++){
+ r[++ri] = cs[j];
+ }
+ for(j = i+1; cj = cs[j]; j++){
+ if(cj._nodup != d){
+ cj._nodup = d;
+ r[++ri] = cj;
+ }
+ }
+ return r;
+ }
+ }
+ return r;
+ }
+
+ function quickDiff(c1, c2){
+ var len1 = c1.length;
+ if(!len1){
+ return c2;
+ }
+ var d = ++key;
+ for(var i = 0; i < len1; i++){
+ c1[i]._qdiff = d;
+ }
+ var r = [];
+ for(var i = 0, len = c2.length; i < len; i++){
+ if(c2[i]._qdiff != d){
+ r[r.length] = c2[i];
+ }
+ }
+ return r;
+ }
+
+ function quickId(ns, mode, root, id){
+ if(ns == root){
+ var d = root.ownerDocument || root;
+ return d.getElementById(id);
+ }
+ ns = getNodes(ns, mode, "*");
+ return byId(ns, null, id);
+ }
+
+ function search(path, root, type) {
+ type = type || "select";
+
+ var n = root || document;
+
+ var q = path, mode, lq;
+ var tk = Ext.DomQuery.matchers;
+ var tklen = tk.length;
+ var mm;
+
+ var lmode = q.match(modeRe);
+ if(lmode && lmode[1]){
+ mode=lmode[1].replace(trimRe, "");
+ q = q.replace(lmode[1], "");
+ }
+ while(path.substr(0, 1)=="/"){
+ path = path.substr(1);
+ }
+ while(q && lq != q){
+ lq = q;
+ var tm = q.match(tagTokenRe);
+ if(type == "select"){
+ if(tm){
+ if(tm[1] == "#"){
+ n = quickId(n, mode, root, tm[2]);
+ }else{
+ n = getNodes(n, mode, tm[2]);
+ }
+ q = q.replace(tm[0], "");
+ }else if(q.substr(0, 1) != '@'){
+ n = getNodes(n, mode, "*");
+ }
+ }else{
+ if(tm){
+ if(tm[1] == "#"){
+ n = byId(n, null, tm[2]);
+ }else{
+ n = byTag(n, tm[2]);
+ }
+ q = q.replace(tm[0], "");
+ }
+ }
+ while(!(mm = q.match(modeRe))){
+ var matched = false;
+ for(var j = 0; j < tklen; j++){
+ var t = tk[j];
+ var m = q.match(t.re);
+ if(m){
+ switch(j) {
+ case 0:
+ n = byClassName(n, null, " " + m[1] +" ");
+ break;
+ case 1:
+ n = byPseudo(n, m[1], m[2]);
+ break;
+ case 2:
+ n = byAttribute(n, m[2], m[4], m[3], m[1]);
+ break;
+ case 3:
+ n = byId(n, null, m[1]);
+ break;
+ case 4:
+ return {firstChild:{nodeValue:attrValue(n, m[1])}};
+
+ }
+ q = q.replace(m[0], "");
+ matched = true;
+ break;
+ }
+ }
+
+ if(!matched){
+ throw 'Error parsing selector, parsing failed at "' + q + '"';
+ }
+ }
+ if(mm[1]){
+ mode=mm[1].replace(trimRe, "");
+ q = q.replace(mm[1], "");
+ }
+ }
+ return nodup(n);
+ }
+
+ return {
+ getStyle : function(el, name){
+ return Ext.fly(el).getStyle(name);
+ },
+
+ compile: function(path, type) {
+ return function(root) {
+ return search(path, root, type);
+ }
+ },
+
+
+ select : function(path, root, type){
+ if(!root || root == document){
+ root = document;
+ }
+ if(typeof root == "string"){
+ root = document.getElementById(root);
+ }
+ var paths = path.split(",");
+ var results = [];
+ for(var i = 0, len = paths.length; i < len; i++){
+ var p = paths[i].replace(trimRe, "");
+ if(!cache[p]){
+ cache[p] = Ext.DomQuery.compile(p);
+ if(!cache[p]){
+ throw p + " is not a valid selector";
+ }
+ }
+ var result = cache[p](root);
+ if(result && result != document){
+ results = results.concat(result);
+ }
+ }
+ if(paths.length > 1){
+ return nodup(results);
+ }
+ return results;
+ },
+
+
+ selectNode : function(path, root){
+ return Ext.DomQuery.select(path, root)[0];
+ },
+
+
+ selectValue : function(path, root, defaultValue){
+ path = path.replace(trimRe, "");
+ if(!valueCache[path]){
+ valueCache[path] = Ext.DomQuery.compile(path, "select");
+ }
+ var n = valueCache[path](root);
+ n = n[0] ? n[0] : n;
+ var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
+ return ((v === null||v === undefined||v==='') ? defaultValue : v);
+ },
+
+
+ selectNumber : function(path, root, defaultValue){
+ var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
+ return parseFloat(v);
+ },
+
+
+ is : function(el, ss){
+ if(typeof el == "string"){
+ el = document.getElementById(el);
+ }
+ var isArray = Ext.isArray(el);
+ var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
+ return isArray ? (result.length == el.length) : (result.length > 0);
+ },
+
+
+ filter : function(els, ss, nonMatches){
+ ss = ss.replace(trimRe, "");
+ if(!simpleCache[ss]){
+ simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
+ }
+ var result = simpleCache[ss](els);
+ return nonMatches ? quickDiff(result, els) : result;
+ },
+
+
+ matchers : [{
+ re: /^\.([\w-]+)/,
+ select: 'n = byClassName(n, null, " {1} ");'
+ }, {
+ re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
+ select: 'n = byPseudo(n, "{1}", "{2}");'
+ },{
+ re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
+ select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
+ }, {
+ re: /^#([\w-]+)/,
+ select: 'n = byId(n, null, "{1}");'
+ },{
+ re: /^@([\w-]+)/,
+ select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
+ }
+ ],
+
+
+ operators : {
+ "=" : function(a, v){
+ return a == v;
+ },
+ "!=" : function(a, v){
+ return a != v;
+ },
+ "^=" : function(a, v){
+ return a && a.substr(0, v.length) == v;
+ },
+ "$=" : function(a, v){
+ return a && a.substr(a.length-v.length) == v;
+ },
+ "*=" : function(a, v){
+ return a && a.indexOf(v) !== -1;
+ },
+ "%=" : function(a, v){
+ return (a % v) == 0;
+ },
+ "|=" : function(a, v){
+ return a && (a == v || a.substr(0, v.length+1) == v+'-');
+ },
+ "~=" : function(a, v){
+ return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
+ }
+ },
+
+
+ pseudos : {
+ "first-child" : function(c){
+ var r = [], ri = -1, n;
+ for(var i = 0, ci; ci = n = c[i]; i++){
+ while((n = n.previousSibling) && n.nodeType != 1);
+ if(!n){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "last-child" : function(c){
+ var r = [], ri = -1, n;
+ for(var i = 0, ci; ci = n = c[i]; i++){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ if(!n){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "nth-child" : function(c, a) {
+ var r = [], ri = -1;
+ var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
+ var f = (m[1] || 1) - 0, l = m[2] - 0;
+ for(var i = 0, n; n = c[i]; i++){
+ var pn = n.parentNode;
+ if (batch != pn._batch) {
+ var j = 0;
+ for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
+ if(cn.nodeType == 1){
+ cn.nodeIndex = ++j;
+ }
+ }
+ pn._batch = batch;
+ }
+ if (f == 1) {
+ if (l == 0 || n.nodeIndex == l){
+ r[++ri] = n;
+ }
+ } else if ((n.nodeIndex + l) % f == 0){
+ r[++ri] = n;
+ }
+ }
+
+ return r;
+ },
+
+ "only-child" : function(c){
+ var r = [], ri = -1;;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(!prev(ci) && !next(ci)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "empty" : function(c){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var cns = ci.childNodes, j = 0, cn, empty = true;
+ while(cn = cns[j]){
+ ++j;
+ if(cn.nodeType == 1 || cn.nodeType == 3){
+ empty = false;
+ break;
+ }
+ }
+ if(empty){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "contains" : function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "nodeValue" : function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(ci.firstChild && ci.firstChild.nodeValue == v){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "checked" : function(c){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(ci.checked == true){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "not" : function(c, ss){
+ return Ext.DomQuery.filter(c, ss, true);
+ },
+
+ "any" : function(c, selectors){
+ var ss = selectors.split('|');
+ var r = [], ri = -1, s;
+ for(var i = 0, ci; ci = c[i]; i++){
+ for(var j = 0; s = ss[j]; j++){
+ if(Ext.DomQuery.is(ci, s)){
+ r[++ri] = ci;
+ break;
+ }
+ }
+ }
+ return r;
+ },
+
+ "odd" : function(c){
+ return this["nth-child"](c, "odd");
+ },
+
+ "even" : function(c){
+ return this["nth-child"](c, "even");
+ },
+
+ "nth" : function(c, a){
+ return c[a-1] || [];
+ },
+
+ "first" : function(c){
+ return c[0] || [];
+ },
+
+ "last" : function(c){
+ return c[c.length-1] || [];
+ },
+
+ "has" : function(c, ss){
+ var s = Ext.DomQuery.select;
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(s(ss, ci).length > 0){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "next" : function(c, ss){
+ var is = Ext.DomQuery.is;
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = next(ci);
+ if(n && is(n, ss)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "prev" : function(c, ss){
+ var is = Ext.DomQuery.is;
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = prev(ci);
+ if(n && is(n, ss)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ }
+ }
+ };
+}();
+
+Ext.query = Ext.DomQuery.select;
+
+Date.precompileFormats = function(s){
+ var formats = s.split('|');
+ for(var i = 0, len = formats.length;i < len;i++){
+ Date.createNewFormat(formats[i]);
+ Date.createParser(formats[i]);
+ }
+}
+
+Date.precompileFormats("D n/j/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|YmdHis|F d, Y|l, F d, Y|H:i:s|g:i A|g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|m/d/y|m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|Y-m-d H:i:s|d/m/y|d/m/Y|d-m-y|d-m-Y|d/m|d-m|dm|dmy|dmY|Y-m-d|l|D m/d|D m/d/Y|m/d/Y");
+
+
+Ext.ColorPalette.prototype.tpl = new Ext.XTemplate(
+ ' '
+);
+
+
+
+
+
+
+
+Ext.air.FileProvider = function(config){
+ Ext.air.FileProvider.superclass.constructor.call(this);
+
+ this.defaultState = {
+ mainWindow : {
+ width:780,
+ height:580,
+ x:10,
+ y:10
+ }
+ };
+
+ Ext.apply(this, config);
+ this.state = this.readState();
+
+ var provider = this;
+ air.NativeApplication.nativeApplication.addEventListener('exiting', function(){
+ provider.saveState();
+ });
+};
+
+Ext.extend(Ext.air.FileProvider, Ext.state.Provider, {
+
+ file: 'extstate.data',
+
+
+
+ readState : function(){
+ var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
+ if(!stateFile.exists){
+ return this.defaultState || {};
+ }
+
+ var stream = new air.FileStream();
+ stream.open(stateFile, air.FileMode.READ);
+
+ var stateData = stream.readObject();
+ stream.close();
+
+ return stateData || this.defaultState || {};
+ },
+
+
+ saveState : function(name, value){
+ var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
+ var stream = new air.FileStream();
+ stream.open(stateFile, air.FileMode.WRITE);
+ stream.writeObject(this.state);
+ stream.close();
+ }
+});
+
+
+Ext.air.NativeObservable = Ext.extend(Ext.util.Observable, {
+ addListener : function(name){
+ this.proxiedEvents = this.proxiedEvents || {};
+ if(!this.proxiedEvents[name]){
+ var instance = this;
+ var f = function(){
+ var args = Array.prototype.slice.call(arguments, 0);
+ args.unshift(name);
+ instance.fireEvent.apply(instance, args);
+ };
+ this.proxiedEvents[name] = f;
+ this.getNative().addEventListener(name, f);
+ }
+ Ext.air.NativeObservable.superclass.addListener.apply(this, arguments);
+ }
+});
+
+Ext.air.NativeObservable.prototype.on = Ext.air.NativeObservable.prototype.addListener;
+
+Ext.air.NativeWindow = function(config){
+ Ext.apply(this, config);
+
+
+ this.id = this.id || Ext.uniqueId();
+
+ this.addEvents(
+
+ 'close',
+
+ 'closing',
+
+ 'move',
+
+ 'moving',
+
+ 'resize',
+
+ 'resizing',
+
+ 'displayStateChange',
+
+ 'displayStateChanging'
+ );
+
+ Ext.air.NativeWindow.superclass.constructor.call(this);
+
+ if(!this.instance){
+ var options = new air.NativeWindowInitOptions();
+ options.systemChrome = this.chrome;
+ options.type = this.type;
+ options.resizable = this.resizable;
+ options.minimizable = this.minimizable;
+ options.maximizable = this.maximizable;
+ options.transparent = this.transparent;
+
+ this.loader = window.runtime.flash.html.HTMLLoader.createRootWindow(false, options, false);
+ this.loader.load(new air.URLRequest(this.file));
+
+ this.instance = this.loader.window.nativeWindow;
+ }else{
+ this.loader = this.instance.stage.getChildAt(0);
+ }
+
+ var provider = Ext.state.Manager;
+ var b = air.Screen.mainScreen.visibleBounds;
+
+ var state = provider.get(this.id) || {};
+ provider.set(this.id, state);
+
+ var win = this.instance;
+
+ var width = Math.max(state.width || this.width, 100);
+ var height = Math.max(state.height || this.height, 100);
+
+ var centerX = b.x + ((b.width/2)-(width/2));
+ var centerY = b.y + ((b.height/2)-(height/2));
+
+ var x = !Ext.isEmpty(state.x, false) ? state.x : (!Ext.isEmpty(this.x, false) ? this.x : centerX);
+ var y = !Ext.isEmpty(state.y, false) ? state.y : (!Ext.isEmpty(this.y, false) ? this.y : centerY);
+
+ win.width = width;
+ win.height = height;
+ win.x = x;
+ win.y = y;
+
+ win.addEventListener('move', function(){
+ if(win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
+ state.x = win.x;
+ state.y = win.y;
+ }
+ });
+ win.addEventListener('resize', function(){
+ if (win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
+ state.width = win.width;
+ state.height = win.height;
+ }
+ });
+
+ Ext.air.NativeWindowManager.register(this);
+ this.on('close', this.unregister, this);
+
+
+ if(this.minimizeToTray){
+ this.initMinimizeToTray(this.trayIcon, this.trayMenu);
+ }
+
+};
+
+Ext.extend(Ext.air.NativeWindow, Ext.air.NativeObservable, {
+
+
+
+
+
+
+
+
+ chrome: 'standard',
+
+ type: 'normal',
+
+ width:600,
+
+ height:400,
+
+ resizable: true,
+
+ minimizable: true,
+
+ maximizable: true,
+
+ transparent: false,
+
+
+ getNative : function(){
+ return this.instance;
+ },
+
+
+ getCenterXY : function(){
+ var b = air.Screen.mainScreen.visibleBounds;
+ return {
+ x: b.x + ((b.width/2)-(this.width/2)),
+ y: b.y + ((b.height/2)-(this.height/2))
+ };
+ },
+
+
+ show :function(){
+ if(this.trayed){
+ Ext.air.SystemTray.hideIcon();
+ this.trayed = false;
+ }
+ this.instance.visible = true;
+ },
+
+
+ activate : function(){
+ this.show();
+ this.instance.activate();
+ },
+
+
+ hide :function(){
+ this.instance.visible = false;
+ },
+
+
+ close : function(){
+ this.instance.close();
+ },
+
+
+ isMinimized :function(){
+ return this.instance.displayState == air.NativeWindowDisplayState.MINIMIZED;
+ },
+
+
+ isMaximized :function(){
+ return this.instance.displayState == air.NativeWindowDisplayState.MAXIMIZED;
+ },
+
+
+ moveTo : function(x, y){
+ this.x = this.instance.x = x;
+ this.y = this.instance.y = y;
+ },
+
+
+ resize : function(width, height){
+ this.width = this.instance.width = width;
+ this.height = this.instance.height = height;
+ },
+
+ unregister : function(){
+ Ext.air.NativeWindowManager.unregister(this);
+ },
+
+ initMinimizeToTray : function(icon, menu){
+ var tray = Ext.air.SystemTray;
+
+ tray.setIcon(icon, this.trayTip);
+ this.on('displayStateChanging', function(e){
+ if(e.afterDisplayState == 'minimized'){
+ e.preventDefault();
+ this.hide();
+ tray.showIcon();
+ this.trayed = true;
+ }
+ }, this);
+
+ tray.on('click', function(){
+ this.activate();
+ }, this);
+
+ if(menu){
+ tray.setMenu(menu);
+ }
+ }
+});
+
+
+Ext.air.NativeWindow.getRootWindow = function(){
+ return air.NativeApplication.nativeApplication.openedWindows[0];
+};
+
+
+Ext.air.NativeWindow.getRootHtmlWindow = function(){
+ return Ext.air.NativeWindow.getRootWindow().stage.getChildAt(0).window;
+};
+
+
+Ext.air.NativeWindowGroup = function(){
+ var list = {};
+
+ return {
+
+ register : function(win){
+ list[win.id] = win;
+ },
+
+
+ unregister : function(win){
+ delete list[win.id];
+ },
+
+
+ get : function(id){
+ return list[id];
+ },
+
+
+ closeAll : function(){
+ for(var id in list){
+ if(list.hasOwnProperty(id)){
+ list[id].close();
+ }
+ }
+ },
+
+
+ each : function(fn, scope){
+ for(var id in list){
+ if(list.hasOwnProperty(id)){
+ if(fn.call(scope || list[id], list[id]) === false){
+ return;
+ }
+ }
+ }
+ }
+ };
+};
+
+
+Ext.air.NativeWindowManager = new Ext.air.NativeWindowGroup();
+
+Ext.sql.Connection = function(config){
+ Ext.apply(this, config);
+ Ext.sql.Connection.superclass.constructor.call(this);
+
+ this.addEvents({
+ open : true,
+ close: true
+ });
+};
+
+Ext.extend(Ext.sql.Connection, Ext.util.Observable, {
+ maxResults: 10000,
+ openState : false,
+
+
+ open : function(file){
+ },
+
+ close : function(){
+ },
+
+ exec : function(sql){
+ },
+
+ execBy : function(sql, args){
+ },
+
+ query : function(sql){
+ },
+
+ queryBy : function(sql, args){
+ },
+
+
+ isOpen : function(){
+ return this.openState;
+ },
+
+ getTable : function(name, keyName){
+ return new Ext.sql.Table(this, name, keyName);
+ },
+
+ createTable : function(o){
+ var tableName = o.name;
+ var keyName = o.key;
+ var fs = o.fields;
+ if(!Ext.isArray(fs)){
+ fs = fs.items;
+ }
+ var buf = [];
+ for(var i = 0, len = fs.length; i < len; i++){
+ var f = fs[i], s = f.name;
+ switch(f.type){
+ case "int":
+ case "bool":
+ case "boolean":
+ s += ' INTEGER';
+ break;
+ case "float":
+ s += ' REAL';
+ break;
+ default:
+ s += ' TEXT';
+ }
+ if(f.allowNull === false || f.name == keyName){
+ s += ' NOT NULL';
+ }
+ if(f.name == keyName){
+ s += ' PRIMARY KEY';
+ }
+ if(f.unique === true){
+ s += ' UNIQUE';
+ }
+
+ buf[buf.length] = s;
+ }
+ var sql = ['CREATE TABLE IF NOT EXISTS ', tableName, ' (', buf.join(','), ')'].join('');
+ this.exec(sql);
+ }
+});
+
+
+Ext.sql.Connection.getInstance = function(db, config){
+ if(Ext.isAir){
+ return new Ext.sql.AirConnection(config);
+ } else {
+ return new Ext.sql.GearsConnection(config);
+ }
+};
+Ext.sql.Table = function(conn, name, keyName){
+ this.conn = conn;
+ this.name = name;
+ this.keyName = keyName;
+};
+
+Ext.sql.Table.prototype = {
+ update : function(o){
+ var clause = this.keyName + " = ?";
+ return this.updateBy(o, clause, [o[this.keyName]]);
+ },
+
+ updateBy : function(o, clause, args){
+ var sql = "UPDATE " + this.name + " set ";
+ var fs = [], a = [];
+ for(var key in o){
+ if(o.hasOwnProperty(key)){
+ fs[fs.length] = key + ' = ?';
+ a[a.length] = o[key];
+ }
+ }
+ for(var key in args){
+ if(args.hasOwnProperty(key)){
+ a[a.length] = args[key];
+ }
+ }
+ sql = [sql, fs.join(','), ' WHERE ', clause].join('');
+ return this.conn.execBy(sql, a);
+ },
+
+ insert : function(o){
+ var sql = "INSERT into " + this.name + " ";
+ var fs = [], vs = [], a = [];
+ for(var key in o){
+ if(o.hasOwnProperty(key)){
+ fs[fs.length] = key;
+ vs[vs.length] = '?';
+ a[a.length] = o[key];
+ }
+ }
+ sql = [sql, '(', fs.join(','), ') VALUES (', vs.join(','), ')'].join('');
+ return this.conn.execBy(sql, a);
+ },
+
+ lookup : function(id){
+ return this.selectBy('where ' + this.keyName + " = ?", [id])[0] || null;
+ },
+
+ exists : function(id){
+ return !!this.lookup(id);
+ },
+
+ save : function(o){
+ if(this.exists(o[this.keyName])){
+ this.update(o);
+ }else{
+ this.insert(o);
+ }
+ },
+
+ select : function(clause){
+ return this.selectBy(clause, null);
+ },
+
+ selectBy : function(clause, args){
+ var sql = "select * from " + this.name;
+ if(clause){
+ sql += ' ' + clause;
+ }
+ args = args || {};
+ return this.conn.queryBy(sql, args);
+ },
+
+ remove : function(clause){
+ this.deleteBy(clause, null);
+ },
+
+ removeBy : function(clause, args){
+ var sql = "delete from " + this.name;
+ if(clause){
+ sql += ' where ' + clause;
+ }
+ args = args || {};
+ this.conn.execBy(sql, args);
+ }
+};
+Ext.sql.Proxy = function(conn, table, keyName, store, readonly){
+ Ext.sql.Proxy.superclass.constructor.call(this);
+ this.conn = conn;
+ this.table = this.conn.getTable(table, keyName);
+ this.store = store;
+
+ if (readonly !== true) {
+ this.store.on('add', this.onAdd, this);
+ this.store.on('update', this.onUpdate, this);
+ this.store.on('remove', this.onRemove, this);
+ }
+};
+
+Ext.sql.Proxy.DATE_FORMAT = 'Y-m-d H:i:s';
+
+Ext.extend(Ext.sql.Proxy, Ext.data.DataProxy, {
+ load : function(params, reader, callback, scope, arg){
+ if(!this.conn.isOpen()){
+ this.conn.on('open', function(){
+ this.load(params, reader, callback, scope, arg);
+ }, this, {single:true});
+ return;
+ };
+ if(this.fireEvent("beforeload", this, params, reader, callback, scope, arg) !== false){
+ var clause = params.where || '';
+ var args = params.args || [];
+ var group = params.groupBy;
+ var sort = params.sort;
+ var dir = params.dir;
+
+ if(group || sort){
+ clause += ' ORDER BY ';
+ if(group && group != sort){
+ clause += group + ' ASC, ';
+ }
+ clause += sort + ' ' + (dir || 'ASC');
+ }
+
+ var rs = this.table.selectBy(clause, args);
+ this.onLoad({callback:callback, scope:scope, arg:arg, reader: reader}, rs);
+ }else{
+ callback.call(scope||this, null, arg, false);
+ }
+ },
+
+ onLoad : function(trans, rs, e, stmt){
+ if(rs === false){
+ this.fireEvent("loadexception", this, null, trans.arg, e);
+ trans.callback.call(trans.scope||window, null, trans.arg, false);
+ return;
+ }
+ var result = trans.reader.readRecords(rs);
+ this.fireEvent("load", this, rs, trans.arg);
+ trans.callback.call(trans.scope||window, result, trans.arg, true);
+ },
+
+ processData : function(o){
+ var fs = this.store.fields;
+ var r = {};
+ for(var key in o){
+ var f = fs.key(key), v = o[key];
+ if(f){
+ if(f.type == 'date'){
+ r[key] = v ? v.format(Ext.sql.Proxy.DATE_FORMAT,10) : '';
+ }else if(f.type == 'boolean'){
+ r[key] = v ? 1 : 0;
+ }else{
+ r[key] = v;
+ }
+ }
+ }
+ return r;
+ },
+
+ onUpdate : function(ds, record){
+ var changes = record.getChanges();
+ var kn = this.table.keyName;
+ this.table.updateBy(this.processData(changes), kn + ' = ?', [record.data[kn]]);
+ record.commit(true);
+ },
+
+ onAdd : function(ds, records, index){
+ for(var i = 0, len = records.length; i < len; i++){
+ this.table.insert(this.processData(records[i].data));
+ }
+ },
+
+ onRemove : function(ds, record, index){
+ var kn = this.table.keyName;
+ this.table.removeBy(kn + ' = ?', [record.data[kn]]);
+ }
+});
+ Ext.sql.AirConnection = Ext.extend(Ext.sql.Connection, {
+
+ open : function(db){
+ this.conn = new air.SQLConnection();
+ var file = air.File.applicationDirectory.resolvePath(db);
+ this.conn.open(file);
+ this.openState = true;
+ this.fireEvent('open', this);
+ },
+
+ close : function(){
+ this.conn.close();
+ this.fireEvent('close', this);
+ },
+
+ createStatement : function(type){
+ var stmt = new air.SQLStatement();
+ stmt.sqlConnection = this.conn;
+ return stmt;
+ },
+
+ exec : function(sql){
+ var stmt = this.createStatement('exec');
+ stmt.text = sql;
+ stmt.execute();
+ },
+
+ execBy : function(sql, args){
+ var stmt = this.createStatement('exec');
+ stmt.text = sql;
+ this.addParams(stmt, args);
+ stmt.execute();
+ },
+
+ query : function(sql){
+ var stmt = this.createStatement('query');
+ stmt.text = sql;
+ stmt.execute(this.maxResults);
+ return this.readResults(stmt.getResult());
+ },
+
+ queryBy : function(sql, args){
+ var stmt = this.createStatement('query');
+ stmt.text = sql;
+ this.addParams(stmt, args);
+ stmt.execute(this.maxResults);
+ return this.readResults(stmt.getResult());
+ },
+
+ addParams : function(stmt, args){
+ if(!args){ return; }
+ for(var key in args){
+ if(args.hasOwnProperty(key)){
+ if(!isNaN(key)){
+ var v = args[key];
+ if(Ext.isDate(v)){
+ v = v.format(Ext.sql.Proxy.DATE_FORMAT);
+ }
+ stmt.parameters[parseInt(key)] = v;
+ }else{
+ stmt.parameters[':' + key] = args[key];
+ }
+ }
+ }
+ return stmt;
+ },
+
+ readResults : function(rs){
+ var r = [];
+ if(rs && rs.data){
+ var len = rs.data.length;
+ for(var i = 0; i < len; i++) {
+ r[r.length] = rs.data[i];
+ }
+ }
+ return r;
+ }
+});
+Ext.air.SystemTray = function(){
+ var app = air.NativeApplication.nativeApplication;
+ var icon, isWindows = false, bitmaps;
+
+
+ if(air.NativeApplication.supportsSystemTrayIcon) {
+ icon = app.icon;
+ isWindows = true;
+ }
+
+
+ if(air.NativeApplication.supportsDockIcon) {
+ icon = app.icon;
+ }
+
+ return {
+
+ setIcon : function(icon, tooltip, initWithIcon){
+ if(!icon){
+ return;
+ }
+ var loader = new air.Loader();
+ loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(e){
+ bitmaps = new runtime.Array(e.target.content.bitmapData);
+ if (initWithIcon) {
+ icon.bitmaps = bitmaps;
+ }
+ });
+ loader.load(new air.URLRequest(icon));
+ if(tooltip && air.NativeApplication.supportsSystemTrayIcon) {
+ app.icon.tooltip = tooltip;
+ }
+ },
+
+ bounce : function(priority){
+ icon.bounce(priority);
+ },
+
+ on : function(eventName, fn, scope){
+ icon.addEventListener(eventName, function(){
+ fn.apply(scope || this, arguments);
+ });
+ },
+
+ hideIcon : function(){
+ if(!icon){
+ return;
+ }
+ icon.bitmaps = [];
+ },
+
+ showIcon : function(){
+ if(!icon){
+ return;
+ }
+ icon.bitmaps = bitmaps;
+ },
+
+ setMenu: function(actions, _parentMenu){
+ if(!icon){
+ return;
+ }
+ var menu = new air.NativeMenu();
+
+ for (var i = 0, len = actions.length; i < len; i++) {
+ var a = actions[i];
+ if(a == '-'){
+ menu.addItem(new air.NativeMenuItem("", true));
+ }else{
+ var item = menu.addItem(Ext.air.MenuItem(a));
+ if(a.menu || (a.initialConfig && a.initialConfig.menu)){
+ item.submenu = Ext.air.SystemTray.setMenu(a.menu || a.initialConfig.menu, menu);
+ }
+ }
+
+ if(!_parentMenu){
+ icon.menu = menu;
+ }
+ }
+
+ return menu;
+ }
+ };
+}();
+
+
+Ext.air.DragType = {
+
+ TEXT : 'text/plain',
+
+ HTML : 'text/html',
+
+ URL : 'text/uri-list',
+
+ BITMAP : 'image/x-vnd.adobe.air.bitmap',
+
+ FILES : 'application/x-vnd.adobe.air.file-list'
+};
+
+
+
+
+Ext.apply(Ext.EventObjectImpl.prototype, {
+ hasFormat : function(format){
+ if (this.browserEvent.dataTransfer) {
+ for (var i = 0, len = this.browserEvent.dataTransfer.types.length; i < len; i++) {
+ if(this.browserEvent.dataTransfer.types[i] == format) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+
+ getData : function(type){
+ return this.browserEvent.dataTransfer.getData(type);
+ }
+});
+
+
+
+
+Ext.air.Sound = {
+
+ play : function(file, startAt){
+ var soundFile = air.File.applicationDirectory.resolvePath(file);
+ var sound = new air.Sound();
+ sound.load(new air.URLRequest(soundFile.url));
+ sound.play(startAt);
+ }
+};
+
+
+Ext.air.SystemMenu = function(){
+ var menu;
+
+ if(air.NativeWindow.supportsMenu && nativeWindow.systemChrome != air.NativeWindowSystemChrome.NONE) {
+ menu = new air.NativeMenu();
+ nativeWindow.menu = menu;
+ }
+
+
+ if(air.NativeApplication.supportsMenu) {
+ menu = air.NativeApplication.nativeApplication.menu;
+ }
+
+ function find(menu, text){
+ for(var i = 0, len = menu.items.length; i < len; i++){
+ if(menu.items[i]['label'] == text){
+ return menu.items[i];
+ }
+ }
+ return null;
+ }
+
+ return {
+
+ add: function(text, actions, mindex){
+
+ var item = find(menu, text);
+ if(!item){
+ item = menu.addItem(new air.NativeMenuItem(text));
+ item.mnemonicIndex = mindex || 0;
+
+ item.submenu = new air.NativeMenu();
+ }
+ for (var i = 0, len = actions.length; i < len; i++) {
+ item.submenu.addItem(actions[i] == '-' ? new air.NativeMenuItem("", true) : Ext.air.MenuItem(actions[i]));
+ }
+ return item.submenu;
+ },
+
+
+ get : function(){
+ return menu;
+ }
+ };
+}();
+
+
+Ext.air.MenuItem = function(action){
+ if(!action.isAction){
+ action = new Ext.Action(action);
+ }
+ var cfg = action.initialConfig;
+ var nativeItem = new air.NativeMenuItem(cfg.itemText || cfg.text);
+
+ nativeItem.enabled = !cfg.disabled;
+
+ if(!Ext.isEmpty(cfg.checked)){
+ nativeItem.checked = cfg.checked;
+ }
+
+ var handler = cfg.handler;
+ var scope = cfg.scope;
+
+ nativeItem.addEventListener(air.Event.SELECT, function(){
+ handler.call(scope || window, cfg);
+ });
+
+ action.addComponent({
+ setDisabled : function(v){
+ nativeItem.enabled = !v;
+ },
+
+ setText : function(v){
+ nativeItem.label = v;
+ },
+
+ setVisible : function(v){
+
+ nativeItem.enabled = !v;
+ },
+
+ setHandler : function(newHandler, newScope){
+ handler = newHandler;
+ scope = newScope;
+ },
+
+ on : function(){}
+ });
+
+ return nativeItem;
+}
+
diff --git a/thirdpartyjs/extjs/air/resources/air-resources.jsb b/thirdpartyjs/extjs/air/resources/air-resources.jsb
new file mode 100644
index 0000000..11908c0
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/air-resources.jsb
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/resources/ext-air.css b/thirdpartyjs/extjs/air/resources/ext-air.css
new file mode 100644
index 0000000..065ec00
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/ext-air.css
@@ -0,0 +1,101 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+body.x-air-window {
+ background:transparent !important;
+ height:100%;
+}
+
+.x-air.x-window-tc {
+ background: transparent url(images/top-bottom.png) repeat-x 0 0;
+ padding-top:11px;
+}
+.x-air.x-window-bc .x-air.x-window-footer {
+ background: transparent url(images/top-bottom.png) repeat-x 0 bottom;
+ padding-bottom:15px;
+}
+.x-panel-nofooter .x-air.x-window-bc {
+ background: transparent url(images/top-bottom.png) repeat-x 0 bottom;
+ height:15px;
+}
+.x-air.x-window-tr {
+ background: transparent url(images/right-corners.png) no-repeat right 0;
+ padding-right:15px;
+}
+.x-air.x-window-br {
+ background: transparent url(images/right-corners.png) no-repeat right bottom;
+ padding-right:15px;
+}
+
+.x-air.x-window-tl {
+ background: transparent url(images/left-corners.png) no-repeat 0 0;
+ padding-left:15px;
+}
+.x-air.x-window-bl {
+ background: transparent url(images/left-corners.png) no-repeat 0 bottom;
+ padding-left:15px;
+}
+
+.x-air.x-window-mr {
+ background: transparent url(images/left-right.png) repeat-y right 0;
+ padding-right:15px;
+}
+
+.x-air.x-window-ml {
+ background: transparent url(images/left-right.png) repeat-y 0 0;
+ padding-left:15px;
+}
+.x-air.x-resizable-handle{
+ margin:7px;
+}
+
+.x-air.x-window-mc {
+ background: #CAD9EC;
+ border-right:1px solid #DFE8F6;
+ border-bottom:1px solid #DFE8F6;
+ border-top:1px solid #a3bae9;
+ border-left:1px solid #a3bae9;
+}
+
+.x-air.x-window-body {
+ border-left:1px solid #DFE8F6;
+ border-top:1px solid #DFE8F6;
+ border-bottom:1px solid #a3bae9;
+ border-right:1px solid #a3bae9;
+ background:transparent !important;
+}
+
+
+.ext-safari .x-small-editor .x-form-field {
+ /* safari text field will not size so needs bigger font */
+ font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-menu-sep {
+ overflow:hidden;
+ height:1px;
+ margin: 1px 3px;
+}
+
+.x-layout-split, .x-splitbar-h, .x-splitbar-v, .x-layout-split-north, .x-layout-split-east, .x-layout-split-west, .x-layout-split-south {
+ cursor:move !important;
+}
+
+.x-grid3:not(input) {
+ -khtml-user-select: none;
+}
+.x-tree:not(input) {
+ -khtml-user-select: none;
+}
+.x-panel:not(input) {
+ -khtml-user-select: none;
+}
+.x-panel .x-panel-body textarea {
+ -khtml-user-select: normal;
+}
+
diff --git a/thirdpartyjs/extjs/air/resources/icons/extlogo128.png b/thirdpartyjs/extjs/air/resources/icons/extlogo128.png
new file mode 100644
index 0000000..51b6862
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/icons/extlogo128.png
diff --git a/thirdpartyjs/extjs/air/resources/icons/extlogo16.png b/thirdpartyjs/extjs/air/resources/icons/extlogo16.png
new file mode 100644
index 0000000..eb33168
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/icons/extlogo16.png
diff --git a/thirdpartyjs/extjs/air/resources/icons/extlogo32.png b/thirdpartyjs/extjs/air/resources/icons/extlogo32.png
new file mode 100644
index 0000000..6263ef5
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/icons/extlogo32.png
diff --git a/thirdpartyjs/extjs/air/resources/icons/extlogo48.png b/thirdpartyjs/extjs/air/resources/icons/extlogo48.png
new file mode 100644
index 0000000..428a4da
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/icons/extlogo48.png
diff --git a/thirdpartyjs/extjs/air/resources/icons/extlogo64.png b/thirdpartyjs/extjs/air/resources/icons/extlogo64.png
new file mode 100644
index 0000000..d9d4fd8
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/icons/extlogo64.png
diff --git a/thirdpartyjs/extjs/air/resources/images/left-corners.png b/thirdpartyjs/extjs/air/resources/images/left-corners.png
new file mode 100644
index 0000000..2f07046
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/images/left-corners.png
diff --git a/thirdpartyjs/extjs/air/resources/images/left-right.png b/thirdpartyjs/extjs/air/resources/images/left-right.png
new file mode 100644
index 0000000..b0a358e
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/images/left-right.png
diff --git a/thirdpartyjs/extjs/air/resources/images/right-corners.png b/thirdpartyjs/extjs/air/resources/images/right-corners.png
new file mode 100644
index 0000000..8bcc811
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/images/right-corners.png
diff --git a/thirdpartyjs/extjs/air/resources/images/top-bottom.png b/thirdpartyjs/extjs/air/resources/images/top-bottom.png
new file mode 100644
index 0000000..96c0535
--- /dev/null
+++ b/thirdpartyjs/extjs/air/resources/images/top-bottom.png
diff --git a/thirdpartyjs/extjs/air/src/FileProvider.js b/thirdpartyjs/extjs/air/src/FileProvider.js
new file mode 100644
index 0000000..acf64b6
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/FileProvider.js
@@ -0,0 +1,75 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+/**
+ * @class Ext.air.FileProvider
+ * @extends Ext.state.Provider
+ *
+ * An Ext state provider implementation for Adobe AIR that stores state in the application
+ * storage directory.
+ *
+ * @constructor
+ * @param {Object} config
+ */
+Ext.air.FileProvider = function(config){
+ Ext.air.FileProvider.superclass.constructor.call(this);
+
+ this.defaultState = {
+ mainWindow : {
+ width:780,
+ height:580,
+ x:10,
+ y:10
+ }
+ };
+
+ Ext.apply(this, config);
+ this.state = this.readState();
+
+ var provider = this;
+ air.NativeApplication.nativeApplication.addEventListener('exiting', function(){
+ provider.saveState();
+ });
+};
+
+Ext.extend(Ext.air.FileProvider, Ext.state.Provider, {
+ /**
+ * @cfg {String} file
+ * The file name to use for the state file in the application storage directory
+ */
+ file: 'extstate.data',
+
+ /**
+ * @cfg {Object} defaultState
+ * The default state if no state file can be found
+ */
+ // private
+ readState : function(){
+ var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
+ if(!stateFile.exists){
+ return this.defaultState || {};
+ }
+
+ var stream = new air.FileStream();
+ stream.open(stateFile, air.FileMode.READ);
+
+ var stateData = stream.readObject();
+ stream.close();
+
+ return stateData || this.defaultState || {};
+ },
+
+ // private
+ saveState : function(name, value){
+ var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
+ var stream = new air.FileStream();
+ stream.open(stateFile, air.FileMode.WRITE);
+ stream.writeObject(this.state);
+ stream.close();
+ }
+});
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/NativeDD.js b/thirdpartyjs/extjs/air/src/NativeDD.js
new file mode 100644
index 0000000..45106fd
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/NativeDD.js
@@ -0,0 +1,60 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+
+/**
+ * @class Ext.air.DragType
+ *
+ * Drag drop type constants
+ *
+ * @singleton
+ */
+Ext.air.DragType = {
+ /**
+ * Constant for text data
+ */
+ TEXT : 'text/plain',
+ /**
+ * Constant for html data
+ */
+ HTML : 'text/html',
+ /**
+ * Constant for url data
+ */
+ URL : 'text/uri-list',
+ /**
+ * Constant for bitmap data
+ */
+ BITMAP : 'image/x-vnd.adobe.air.bitmap',
+ /**
+ * Constant for file list data
+ */
+ FILES : 'application/x-vnd.adobe.air.file-list'
+};
+
+
+// workaround for DD dataTransfer Clipboard not having hasFormat
+
+Ext.apply(Ext.EventObjectImpl.prototype, {
+ hasFormat : function(format){
+ if (this.browserEvent.dataTransfer) {
+ for (var i = 0, len = this.browserEvent.dataTransfer.types.length; i < len; i++) {
+ if(this.browserEvent.dataTransfer.types[i] == format) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+
+ getData : function(type){
+ return this.browserEvent.dataTransfer.getData(type);
+ }
+});
+
+
diff --git a/thirdpartyjs/extjs/air/src/NativeObservable.js b/thirdpartyjs/extjs/air/src/NativeObservable.js
new file mode 100644
index 0000000..d9bb4b7
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/NativeObservable.js
@@ -0,0 +1,35 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+/**
+ * @class Ext.air.NativeObservable
+ * @extends Ext.util.Observable
+ *
+ * Adds ability for Ext Observable functionality to proxy events for native (AIR) object wrappers
+ *
+ * @constructor
+ */
+
+Ext.air.NativeObservable = Ext.extend(Ext.util.Observable, {
+ addListener : function(name){
+ this.proxiedEvents = this.proxiedEvents || {};
+ if(!this.proxiedEvents[name]){
+ var instance = this;
+ var f = function(){
+ var args = Array.prototype.slice.call(arguments, 0);
+ args.unshift(name);
+ instance.fireEvent.apply(instance, args);
+ };
+ this.proxiedEvents[name] = f;
+ this.getNative().addEventListener(name, f);
+ }
+ Ext.air.NativeObservable.superclass.addListener.apply(this, arguments);
+ }
+});
+
+Ext.air.NativeObservable.prototype.on = Ext.air.NativeObservable.prototype.addListener;
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/NativeWindow.js b/thirdpartyjs/extjs/air/src/NativeWindow.js
new file mode 100644
index 0000000..87cb59f
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/NativeWindow.js
@@ -0,0 +1,397 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+/**
+ * @class Ext.air.NativeWindow
+ * @extends Ext.air.NativeObservable
+ *
+ * Wraps the AIR NativeWindow class to give an Ext friendly API.
This class also adds
+ * automatic state management (position and size) for the window (by id) and it can be used
+ * for easily creating "minimize to system tray" for the main window in your application.
+ *
+ * Note: Many of the config options for this class can only be applied to NEW windows. Passing
+ * in an existing instance of a window along with those config options will have no effect.
+ *
+ * @constructor
+ * @param {Object} config
+ */
+Ext.air.NativeWindow = function(config){
+ Ext.apply(this, config);
+
+ /**
+ * @type String
+ */
+ this.id = this.id || Ext.uniqueId();
+
+ this.addEvents(
+ /**
+ * @event close
+ * @param {Object} e The air event object
+ */
+ 'close',
+ /**
+ * @event closing
+ * @param {Object} e The air event object
+ */
+ 'closing',
+ /**
+ * @event move
+ * @param {Object} e The air event object
+ */
+ 'move',
+ /**
+ * @event moving
+ * @param {Object} e The air event object
+ */
+ 'moving',
+ /**
+ * @event resize
+ * @param {Object} e The air event object
+ */
+ 'resize',
+ /**
+ * @event resizing
+ * @param {Object} e The air event object
+ */
+ 'resizing',
+ /**
+ * @event displayStateChange
+ * @param {Object} e The air event object
+ */
+ 'displayStateChange',
+ /**
+ * @event displayStateChanging
+ * @param {Object} e The air event object
+ */
+ 'displayStateChanging'
+ );
+
+ Ext.air.NativeWindow.superclass.constructor.call(this);
+
+ if(!this.instance){
+ var options = new air.NativeWindowInitOptions();
+ options.systemChrome = this.chrome;
+ options.type = this.type;
+ options.resizable = this.resizable;
+ options.minimizable = this.minimizable;
+ options.maximizable = this.maximizable;
+ options.transparent = this.transparent;
+
+ this.loader = window.runtime.flash.html.HTMLLoader.createRootWindow(false, options, false);
+ this.loader.load(new air.URLRequest(this.file));
+
+ this.instance = this.loader.window.nativeWindow;
+ }else{
+ this.loader = this.instance.stage.getChildAt(0);
+ }
+
+ var provider = Ext.state.Manager;
+ var b = air.Screen.mainScreen.visibleBounds;
+
+ var state = provider.get(this.id) || {};
+ provider.set(this.id, state);
+
+ var win = this.instance;
+
+ var width = Math.max(state.width || this.width, 100);
+ var height = Math.max(state.height || this.height, 100);
+
+ var centerX = b.x + ((b.width/2)-(width/2));
+ var centerY = b.y + ((b.height/2)-(height/2));
+
+ var x = !Ext.isEmpty(state.x, false) ? state.x : (!Ext.isEmpty(this.x, false) ? this.x : centerX);
+ var y = !Ext.isEmpty(state.y, false) ? state.y : (!Ext.isEmpty(this.y, false) ? this.y : centerY);
+
+ win.width = width;
+ win.height = height;
+ win.x = x;
+ win.y = y;
+
+ win.addEventListener('move', function(){
+ if(win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
+ state.x = win.x;
+ state.y = win.y;
+ }
+ });
+ win.addEventListener('resize', function(){
+ if (win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
+ state.width = win.width;
+ state.height = win.height;
+ }
+ });
+
+ Ext.air.NativeWindowManager.register(this);
+ this.on('close', this.unregister, this);
+
+ /**
+ * @cfg {Boolean} minimizeToTray
+ * True to enable minimizing to the system tray. Note: this should only be applied
+ * to the primary window in your application. A trayIcon is required.
+ */
+ if(this.minimizeToTray){
+ this.initMinimizeToTray(this.trayIcon, this.trayMenu);
+ }
+
+};
+
+Ext.extend(Ext.air.NativeWindow, Ext.air.NativeObservable, {
+
+ /**
+ * @cfg {air.NativeWindow} instance
+ * The native window instance to wrap. If undefined, a new window will be created.
+ */
+
+ /**
+ * @cfg {String} trayIcon
+ * The icon to display when minimized in the system tray
+ */
+ /**
+ * @cfg {NativeMenu} trayMenu
+ * Menu to display when the tray icon is right clicked
+ */
+ /**
+ * @cfg {String} trayTip
+ * Tooltip for the tray icon
+ */
+
+ /**
+ * @cfg {String} chrome
+ * The native window chrome (defaults to 'standard', can also be 'none').
+ */
+ chrome: 'standard', // can also be none
+ /**
+ * @cfg {String} type
+ * The native window type - normal, utility or lightweight. (defaults to normal)
+ */
+ type: 'normal', // can be normal, utility or lightweight
+ /**
+ * @cfg {Number} width
+ */
+ width:600,
+ /**
+ * @cfg {Number} height
+ */
+ height:400,
+ /**
+ * @cfg {Boolean} resizable
+ */
+ resizable: true,
+ /**
+ * @cfg {Boolean} minimizable
+ */
+ minimizable: true,
+ /**
+ * @cfg {Boolean} maximizable
+ */
+ maximizable: true,
+ /**
+ * @cfg {Boolean} transparent
+ */
+ transparent: false,
+
+ /**
+ * Returns the air.NativeWindow instance
+ * @return air.NativeWindow
+ */
+ getNative : function(){
+ return this.instance;
+ },
+
+ /**
+ * Returns the x/y coordinates for centering the windw on the screen
+ * @return {x: Number, y: Number}
+ */
+ getCenterXY : function(){
+ var b = air.Screen.mainScreen.visibleBounds;
+ return {
+ x: b.x + ((b.width/2)-(this.width/2)),
+ y: b.y + ((b.height/2)-(this.height/2))
+ };
+ },
+
+ /**
+ * Shows the window
+ */
+ show :function(){
+ if(this.trayed){
+ Ext.air.SystemTray.hideIcon();
+ this.trayed = false;
+ }
+ this.instance.visible = true;
+ },
+
+ /**
+ * Shows and activates the window
+ */
+ activate : function(){
+ this.show();
+ this.instance.activate();
+ },
+
+ /**
+ * Hides the window
+ */
+ hide :function(){
+ this.instance.visible = false;
+ },
+
+ /**
+ * Closes the window
+ */
+ close : function(){
+ this.instance.close();
+ },
+
+ /**
+ * Returns true if this window is minimized
+ * @return Boolean
+ */
+ isMinimized :function(){
+ return this.instance.displayState == air.NativeWindowDisplayState.MINIMIZED;
+ },
+
+ /**
+ * Returns true if this window is maximized
+ * @return Boolean
+ */
+ isMaximized :function(){
+ return this.instance.displayState == air.NativeWindowDisplayState.MAXIMIZED;
+ },
+
+ /**
+ * Moves the window to the passed xy and y coordinates
+ * @param {Number} x
+ * @param {Number} y
+ */
+ moveTo : function(x, y){
+ this.x = this.instance.x = x;
+ this.y = this.instance.y = y;
+ },
+
+ /**
+ * @param {Number} width
+ * @param {Number} height
+ */
+ resize : function(width, height){
+ this.width = this.instance.width = width;
+ this.height = this.instance.height = height;
+ },
+
+ unregister : function(){
+ Ext.air.NativeWindowManager.unregister(this);
+ },
+
+ initMinimizeToTray : function(icon, menu){
+ var tray = Ext.air.SystemTray;
+
+ tray.setIcon(icon, this.trayTip);
+ this.on('displayStateChanging', function(e){
+ if(e.afterDisplayState == 'minimized'){
+ e.preventDefault();
+ this.hide();
+ tray.showIcon();
+ this.trayed = true;
+ }
+ }, this);
+
+ tray.on('click', function(){
+ this.activate();
+ }, this);
+
+ if(menu){
+ tray.setMenu(menu);
+ }
+ }
+});
+
+/**
+ * Returns the first opened window in your application
+ * @return air.NativeWindow
+ * @static
+ */
+Ext.air.NativeWindow.getRootWindow = function(){
+ return air.NativeApplication.nativeApplication.openedWindows[0];
+};
+
+/**
+ * Returns the javascript "window" object of the first opened window in your application
+ * @return Window
+ * @static
+ */
+Ext.air.NativeWindow.getRootHtmlWindow = function(){
+ return Ext.air.NativeWindow.getRootWindow().stage.getChildAt(0).window;
+};
+
+/**
+ * @class Ext.air.NativeWindowGroup
+ *
+ * A collection of NativeWindows.
+ */
+Ext.air.NativeWindowGroup = function(){
+ var list = {};
+
+ return {
+ /**
+ * @param {Object} win
+ */
+ register : function(win){
+ list[win.id] = win;
+ },
+
+ /**
+ * @param {Object} win
+ */
+ unregister : function(win){
+ delete list[win.id];
+ },
+
+ /**
+ * @param {String} id
+ */
+ get : function(id){
+ return list[id];
+ },
+
+ /**
+ * Closes all windows
+ */
+ closeAll : function(){
+ for(var id in list){
+ if(list.hasOwnProperty(id)){
+ list[id].close();
+ }
+ }
+ },
+
+ /**
+ * Executes the specified function once for every window in the group, passing each
+ * window as the only parameter. Returning false from the function will stop the iteration.
+ * @param {Function} fn The function to execute for each item
+ * @param {Object} scope (optional) The scope in which to execute the function
+ */
+ each : function(fn, scope){
+ for(var id in list){
+ if(list.hasOwnProperty(id)){
+ if(fn.call(scope || list[id], list[id]) === false){
+ return;
+ }
+ }
+ }
+ }
+ };
+};
+
+/**
+ * @class Ext.air.NativeWindowManager
+ * @extends Ext.air.NativeWindowGroup
+ *
+ * Collection of all NativeWindows created.
+ *
+ * @singleton
+ */
+Ext.air.NativeWindowManager = new Ext.air.NativeWindowGroup();
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/Sound.js b/thirdpartyjs/extjs/air/src/Sound.js
new file mode 100644
index 0000000..77c152b
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/Sound.js
@@ -0,0 +1,26 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+/**
+ * @class Ext.air.Sound
+ *
+ * @singleton
+ */
+Ext.air.Sound = {
+ /**
+ * Play a sound.
+ * @param {String} file The file to be played. The path is resolved against applicationDirectory
+ * @param {Number} startAt (optional) A time in the sound file to skip to before playing
+ */
+ play : function(file, startAt){
+ var soundFile = air.File.applicationDirectory.resolvePath(file);
+ var sound = new air.Sound();
+ sound.load(new air.URLRequest(soundFile.url));
+ sound.play(startAt);
+ }
+};
diff --git a/thirdpartyjs/extjs/air/src/SystemMenu.js b/thirdpartyjs/extjs/air/src/SystemMenu.js
new file mode 100644
index 0000000..3616dfd
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/SystemMenu.js
@@ -0,0 +1,118 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+/**
+ * @class Ext.air.SystemMenu
+ *
+ * Provides platform independent handling of adding item to the application menu, creating the menu or
+ * items as needed.
+ *
+ * This class also provides the ability to bind standard Ext.Action instances with NativeMenuItems
+ *
+ * @singleton
+ */
+Ext.air.SystemMenu = function(){
+ var menu;
+ // windows
+ if(air.NativeWindow.supportsMenu && nativeWindow.systemChrome != air.NativeWindowSystemChrome.NONE) {
+ menu = new air.NativeMenu();
+ nativeWindow.menu = menu;
+ }
+
+ // mac
+ if(air.NativeApplication.supportsMenu) {
+ menu = air.NativeApplication.nativeApplication.menu;
+ }
+
+ function find(menu, text){
+ for(var i = 0, len = menu.items.length; i < len; i++){
+ if(menu.items[i]['label'] == text){
+ return menu.items[i];
+ }
+ }
+ return null;
+ }
+
+ return {
+ /**
+ * Add items to one of the application menus
+ * @param {String} text The application menu to add the actions to (e.g. 'File' or 'Edit').
+ * @param {Array} actions An array of Ext.Action objects or menu item configs
+ * @param {Number} mindex The index of the character in "text" which should be used for
+ * keyboard access
+ * @return air.NativeMenu The raw submenu
+ */
+ add: function(text, actions, mindex){
+
+ var item = find(menu, text);
+ if(!item){
+ item = menu.addItem(new air.NativeMenuItem(text));
+ item.mnemonicIndex = mindex || 0;
+
+ item.submenu = new air.NativeMenu();
+ }
+ for (var i = 0, len = actions.length; i < len; i++) {
+ item.submenu.addItem(actions[i] == '-' ? new air.NativeMenuItem("", true) : Ext.air.MenuItem(actions[i]));
+ }
+ return item.submenu;
+ },
+
+ /**
+ * Returns the application menu
+ */
+ get : function(){
+ return menu;
+ }
+ };
+}();
+
+// ability to bind native menu items to an Ext.Action
+Ext.air.MenuItem = function(action){
+ if(!action.isAction){
+ action = new Ext.Action(action);
+ }
+ var cfg = action.initialConfig;
+ var nativeItem = new air.NativeMenuItem(cfg.itemText || cfg.text);
+
+ nativeItem.enabled = !cfg.disabled;
+
+ if(!Ext.isEmpty(cfg.checked)){
+ nativeItem.checked = cfg.checked;
+ }
+
+ var handler = cfg.handler;
+ var scope = cfg.scope;
+
+ nativeItem.addEventListener(air.Event.SELECT, function(){
+ handler.call(scope || window, cfg);
+ });
+
+ action.addComponent({
+ setDisabled : function(v){
+ nativeItem.enabled = !v;
+ },
+
+ setText : function(v){
+ nativeItem.label = v;
+ },
+
+ setVisible : function(v){
+ // could not find way to hide in air so disable?
+ nativeItem.enabled = !v;
+ },
+
+ setHandler : function(newHandler, newScope){
+ handler = newHandler;
+ scope = newScope;
+ },
+ // empty function
+ on : function(){}
+ });
+
+ return nativeItem;
+}
diff --git a/thirdpartyjs/extjs/air/src/SystemTray.js b/thirdpartyjs/extjs/air/src/SystemTray.js
new file mode 100644
index 0000000..97241f0
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/SystemTray.js
@@ -0,0 +1,92 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+Ext.air.SystemTray = function(){
+ var app = air.NativeApplication.nativeApplication;
+ var icon, isWindows = false, bitmaps;
+
+ // windows
+ if(air.NativeApplication.supportsSystemTrayIcon) {
+ icon = app.icon;
+ isWindows = true;
+ }
+
+ // mac
+ if(air.NativeApplication.supportsDockIcon) {
+ icon = app.icon;
+ }
+
+ return {
+
+ setIcon : function(icon, tooltip, initWithIcon){
+ if(!icon){ // not supported OS
+ return;
+ }
+ var loader = new air.Loader();
+ loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(e){
+ bitmaps = new runtime.Array(e.target.content.bitmapData);
+ if (initWithIcon) {
+ icon.bitmaps = bitmaps;
+ }
+ });
+ loader.load(new air.URLRequest(icon));
+ if(tooltip && air.NativeApplication.supportsSystemTrayIcon) {
+ app.icon.tooltip = tooltip;
+ }
+ },
+
+ bounce : function(priority){
+ icon.bounce(priority);
+ },
+
+ on : function(eventName, fn, scope){
+ icon.addEventListener(eventName, function(){
+ fn.apply(scope || this, arguments);
+ });
+ },
+
+ hideIcon : function(){
+ if(!icon){ // not supported OS
+ return;
+ }
+ icon.bitmaps = [];
+ },
+
+ showIcon : function(){
+ if(!icon){ // not supported OS
+ return;
+ }
+ icon.bitmaps = bitmaps;
+ },
+
+ setMenu: function(actions, _parentMenu){
+ if(!icon){ // not supported OS
+ return;
+ }
+ var menu = new air.NativeMenu();
+
+ for (var i = 0, len = actions.length; i < len; i++) {
+ var a = actions[i];
+ if(a == '-'){
+ menu.addItem(new air.NativeMenuItem("", true));
+ }else{
+ var item = menu.addItem(Ext.air.MenuItem(a));
+ if(a.menu || (a.initialConfig && a.initialConfig.menu)){
+ item.submenu = Ext.air.SystemTray.setMenu(a.menu || a.initialConfig.menu, menu);
+ }
+ }
+
+ if(!_parentMenu){
+ icon.menu = menu;
+ }
+ }
+
+ return menu;
+ }
+ };
+}();
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/air.jsb b/thirdpartyjs/extjs/air/src/air.jsb
new file mode 100644
index 0000000..4302ca0
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/air.jsb
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/ext-air-adapter.js b/thirdpartyjs/extjs/air/src/ext-air-adapter.js
new file mode 100644
index 0000000..6bbcb86
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/ext-air-adapter.js
@@ -0,0 +1,797 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+/*
+ * This file corrects air eval issues and other issues found in the AIR application sandbox
+ */
+Ext.namespace('Ext.air', 'Ext.sql');
+
+Ext.Template.prototype.compile = function() {
+ var fm = Ext.util.Format;
+ var useF = this.disableFormats !== true;
+ //
+ var prevOffset = 0;
+ var arr = [];
+ var tpl = this;
+ var fn = function(m, name, format, args, offset, s){
+ if (prevOffset != offset) {
+ var action = {type: 1, value: s.substr(prevOffset, offset - prevOffset)};
+ arr.push(action);
+ }
+ prevOffset = offset + m.length;
+ if(format && useF){
+ if (args) {
+ var re = /^\s*['"](.*)["']\s*$/;
+ args = args.split(/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/);
+ for(var i = 0, len = args.length; i < len; i++){
+ args[i] = args[i].replace(re, "$1");
+ }
+ args = [''].concat(args);
+ } else {
+ args = [''];
+ }
+ if(format.substr(0, 5) != "this."){
+ var action = {type: 3, value:name, format: fm[format], args: args, scope: fm};
+ arr.push(action);
+ }else{
+ var action = {type: 3, value:name, format:tpl[format.substr(5)], args:args, scope: tpl};
+ arr.push(action);
+ }
+ }else{
+ var action = {type: 2, value: name};
+ arr.push(action);
+ }
+ return m;
+ };
+
+ var s = this.html.replace(this.re, fn);
+ if (prevOffset != (s.length - 1)) {
+ var action = {type: 1, value: s.substr(prevOffset, s.length - prevOffset)};
+ arr.push(action);
+ }
+
+ this.compiled = function(values) {
+ function applyValues(el) {
+ switch (el.type) {
+ case 1:
+ return el.value;
+ case 2:
+ return (values[el.value] ? values[el.value] : '');
+ default:
+ el.args[0] = values[el.value];
+ return el.format.apply(el.scope, el.args);
+ }
+ }
+ return arr.map(applyValues).join('');
+ }
+ return this;
+};
+
+Ext.Template.prototype.call = function(fnName, value, allValues){
+ return this[fnName](value, allValues);
+}
+
+
+Ext.DomQuery = function(){
+ var cache = {}, simpleCache = {}, valueCache = {};
+ var nonSpace = /\S/;
+ var trimRe = /^\s+|\s+$/g;
+ var tplRe = /\{(\d+)\}/g;
+ var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
+ var tagTokenRe = /^(#)?([\w-\*]+)/;
+ var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
+
+ function child(p, index){
+ var i = 0;
+ var n = p.firstChild;
+ while(n){
+ if(n.nodeType == 1){
+ if(++i == index){
+ return n;
+ }
+ }
+ n = n.nextSibling;
+ }
+ return null;
+ };
+
+ function next(n){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ return n;
+ };
+
+ function prev(n){
+ while((n = n.previousSibling) && n.nodeType != 1);
+ return n;
+ };
+
+ function children(d){
+ var n = d.firstChild, ni = -1;
+ while(n){
+ var nx = n.nextSibling;
+ if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
+ d.removeChild(n);
+ }else{
+ n.nodeIndex = ++ni;
+ }
+ n = nx;
+ }
+ return this;
+ };
+
+ function byClassName(c, a, v){
+ if(!v){
+ return c;
+ }
+ var r = [], ri = -1, cn;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if((' '+ci.className+' ').indexOf(v) != -1){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ };
+
+ function attrValue(n, attr){
+ if(!n.tagName && typeof n.length != "undefined"){
+ n = n[0];
+ }
+ if(!n){
+ return null;
+ }
+ if(attr == "for"){
+ return n.htmlFor;
+ }
+ if(attr == "class" || attr == "className"){
+ return n.className;
+ }
+ return n.getAttribute(attr) || n[attr];
+
+ };
+
+ function getNodes(ns, mode, tagName){
+ var result = [], ri = -1, cs;
+ if(!ns){
+ return result;
+ }
+ tagName = tagName || "*";
+ if(typeof ns.getElementsByTagName != "undefined"){
+ ns = [ns];
+ }
+ if(!mode){
+ for(var i = 0, ni; ni = ns[i]; i++){
+ cs = ni.getElementsByTagName(tagName);
+ for(var j = 0, ci; ci = cs[j]; j++){
+ result[++ri] = ci;
+ }
+ }
+ }else if(mode == "/" || mode == ">"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, ni, cn; ni = ns[i]; i++){
+ cn = ni.children || ni.childNodes;
+ for(var j = 0, cj; cj = cn[j]; j++){
+ if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
+ result[++ri] = cj;
+ }
+ }
+ }
+ }else if(mode == "+"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, n; n = ns[i]; i++){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
+ result[++ri] = n;
+ }
+ }
+ }else if(mode == "~"){
+ for(var i = 0, n; n = ns[i]; i++){
+ while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
+ if(n){
+ result[++ri] = n;
+ }
+ }
+ }
+ return result;
+ };
+
+ function concat(a, b){
+ if(b.slice){
+ return a.concat(b);
+ }
+ for(var i = 0, l = b.length; i < l; i++){
+ a[a.length] = b[i];
+ }
+ return a;
+ }
+
+ function byTag(cs, tagName){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!tagName){
+ return cs;
+ }
+ var r = [], ri = -1;
+ tagName = tagName.toLowerCase();
+ for(var i = 0, ci; ci = cs[i]; i++){
+ if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ };
+
+ function byId(cs, attr, id){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!id){
+ return cs;
+ }
+ var r = [], ri = -1;
+ for(var i = 0,ci; ci = cs[i]; i++){
+ if(ci && ci.id == id){
+ r[++ri] = ci;
+ return r;
+ }
+ }
+ return r;
+ };
+
+ function byAttribute(cs, attr, value, op, custom){
+ var r = [], ri = -1, st = custom=="{";
+ var f = Ext.DomQuery.operators[op];
+ for(var i = 0, ci; ci = cs[i]; i++){
+ var a;
+ if(st){
+ a = Ext.DomQuery.getStyle(ci, attr);
+ }
+ else if(attr == "class" || attr == "className"){
+ a = ci.className;
+ }else if(attr == "for"){
+ a = ci.htmlFor;
+ }else if(attr == "href"){
+ a = ci.getAttribute("href", 2);
+ }else{
+ a = ci.getAttribute(attr);
+ }
+ if((f && f(a, value)) || (!f && a)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ };
+
+ function byPseudo(cs, name, value){
+ return Ext.DomQuery.pseudos[name](cs, value);
+ };
+
+
+ // this eval is stop the compressor from
+ // renaming the variable to something shorter
+ eval("var batch = 30803;");
+
+ var key = 30803;
+
+ function nodup(cs){
+ if(!cs){
+ return [];
+ }
+ var len = cs.length, c, i, r = cs, cj, ri = -1;
+ if(!len || typeof cs.nodeType != "undefined" || len == 1){
+ return cs;
+ }
+ var d = ++key;
+ cs[0]._nodup = d;
+ for(i = 1; c = cs[i]; i++){
+ if(c._nodup != d){
+ c._nodup = d;
+ }else{
+ r = [];
+ for(var j = 0; j < i; j++){
+ r[++ri] = cs[j];
+ }
+ for(j = i+1; cj = cs[j]; j++){
+ if(cj._nodup != d){
+ cj._nodup = d;
+ r[++ri] = cj;
+ }
+ }
+ return r;
+ }
+ }
+ return r;
+ }
+
+ function quickDiff(c1, c2){
+ var len1 = c1.length;
+ if(!len1){
+ return c2;
+ }
+ var d = ++key;
+ for(var i = 0; i < len1; i++){
+ c1[i]._qdiff = d;
+ }
+ var r = [];
+ for(var i = 0, len = c2.length; i < len; i++){
+ if(c2[i]._qdiff != d){
+ r[r.length] = c2[i];
+ }
+ }
+ return r;
+ }
+
+ function quickId(ns, mode, root, id){
+ if(ns == root){
+ var d = root.ownerDocument || root;
+ return d.getElementById(id);
+ }
+ ns = getNodes(ns, mode, "*");
+ return byId(ns, null, id);
+ }
+
+ function search(path, root, type) {
+ type = type || "select";
+ //
+ var n = root || document;
+ //
+ var q = path, mode, lq;
+ var tk = Ext.DomQuery.matchers;
+ var tklen = tk.length;
+ var mm;
+
+ var lmode = q.match(modeRe);
+ if(lmode && lmode[1]){
+ mode=lmode[1].replace(trimRe, "");
+ q = q.replace(lmode[1], "");
+ }
+ while(path.substr(0, 1)=="/"){
+ path = path.substr(1);
+ }
+ while(q && lq != q){
+ lq = q;
+ var tm = q.match(tagTokenRe);
+ if(type == "select"){
+ if(tm){
+ if(tm[1] == "#"){
+ n = quickId(n, mode, root, tm[2]);
+ }else{
+ n = getNodes(n, mode, tm[2]);
+ }
+ q = q.replace(tm[0], "");
+ }else if(q.substr(0, 1) != '@'){
+ n = getNodes(n, mode, "*");
+ }
+ }else{
+ if(tm){
+ if(tm[1] == "#"){
+ n = byId(n, null, tm[2]);
+ }else{
+ n = byTag(n, tm[2]);
+ }
+ q = q.replace(tm[0], "");
+ }
+ }
+ while(!(mm = q.match(modeRe))){
+ var matched = false;
+ for(var j = 0; j < tklen; j++){
+ var t = tk[j];
+ var m = q.match(t.re);
+ if(m){
+ switch(j) {
+ case 0:
+ n = byClassName(n, null, " " + m[1] +" ");
+ break;
+ case 1:
+ n = byPseudo(n, m[1], m[2]);
+ break;
+ case 2:
+ n = byAttribute(n, m[2], m[4], m[3], m[1]);
+ break;
+ case 3:
+ n = byId(n, null, m[1]);
+ break;
+ case 4:
+ return {firstChild:{nodeValue:attrValue(n, m[1])}};
+
+ }
+ q = q.replace(m[0], "");
+ matched = true;
+ break;
+ }
+ }
+
+ if(!matched){
+ throw 'Error parsing selector, parsing failed at "' + q + '"';
+ }
+ }
+ if(mm[1]){
+ mode=mm[1].replace(trimRe, "");
+ q = q.replace(mm[1], "");
+ }
+ }
+ return nodup(n);
+ }
+
+ return {
+ getStyle : function(el, name){
+ return Ext.fly(el).getStyle(name);
+ },
+
+ compile: function(path, type) {
+ return function(root) {
+ return search(path, root, type);
+ }
+ },
+
+ /**
+ * Selects a group of elements.
+ * @param {String} selector The selector/xpath query (can be a comma separated list of selectors)
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Array}
+ */
+ select : function(path, root, type){
+ if(!root || root == document){
+ root = document;
+ }
+ if(typeof root == "string"){
+ root = document.getElementById(root);
+ }
+ var paths = path.split(",");
+ var results = [];
+ for(var i = 0, len = paths.length; i < len; i++){
+ var p = paths[i].replace(trimRe, "");
+ if(!cache[p]){
+ cache[p] = Ext.DomQuery.compile(p);
+ if(!cache[p]){
+ throw p + " is not a valid selector";
+ }
+ }
+ var result = cache[p](root);
+ if(result && result != document){
+ results = results.concat(result);
+ }
+ }
+ if(paths.length > 1){
+ return nodup(results);
+ }
+ return results;
+ },
+
+ /**
+ * Selects a single element.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Element}
+ */
+ selectNode : function(path, root){
+ return Ext.DomQuery.select(path, root)[0];
+ },
+
+ /**
+ * Selects the value of a node, optionally replacing null with the defaultValue.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @param {String} defaultValue
+ */
+ selectValue : function(path, root, defaultValue){
+ path = path.replace(trimRe, "");
+ if(!valueCache[path]){
+ valueCache[path] = Ext.DomQuery.compile(path, "select");
+ }
+ var n = valueCache[path](root);
+ n = n[0] ? n[0] : n;
+ var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
+ return ((v === null||v === undefined||v==='') ? defaultValue : v);
+ },
+
+ /**
+ * Selects the value of a node, parsing integers and floats.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @param {Number} defaultValue
+ * @return {Number}
+ */
+ selectNumber : function(path, root, defaultValue){
+ var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
+ return parseFloat(v);
+ },
+
+ /**
+ * Returns true if the passed element(s) match the passed simple selector (e.g. div.some-class or span:first-child)
+ * @param {String/HTMLElement/Array} el An element id, element or array of elements
+ * @param {String} selector The simple selector to test
+ * @return {Boolean}
+ */
+ is : function(el, ss){
+ if(typeof el == "string"){
+ el = document.getElementById(el);
+ }
+ var isArray = Ext.isArray(el);
+ var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
+ return isArray ? (result.length == el.length) : (result.length > 0);
+ },
+
+ /**
+ * Filters an array of elements to only include matches of a simple selector (e.g. div.some-class or span:first-child)
+ * @param {Array} el An array of elements to filter
+ * @param {String} selector The simple selector to test
+ * @param {Boolean} nonMatches If true, it returns the elements that DON'T match
+ * the selector instead of the ones that match
+ * @return {Array}
+ */
+ filter : function(els, ss, nonMatches){
+ ss = ss.replace(trimRe, "");
+ if(!simpleCache[ss]){
+ simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
+ }
+ var result = simpleCache[ss](els);
+ return nonMatches ? quickDiff(result, els) : result;
+ },
+
+ /**
+ * Collection of matching regular expressions and code snippets.
+ */
+ matchers : [{
+ re: /^\.([\w-]+)/,
+ select: 'n = byClassName(n, null, " {1} ");'
+ }, {
+ re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
+ select: 'n = byPseudo(n, "{1}", "{2}");'
+ },{
+ re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
+ select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
+ }, {
+ re: /^#([\w-]+)/,
+ select: 'n = byId(n, null, "{1}");'
+ },{
+ re: /^@([\w-]+)/,
+ select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
+ }
+ ],
+
+ /**
+ * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=.
+ * New operators can be added as long as the match the format c= where c is any character other than space, > <.
+ */
+ operators : {
+ "=" : function(a, v){
+ return a == v;
+ },
+ "!=" : function(a, v){
+ return a != v;
+ },
+ "^=" : function(a, v){
+ return a && a.substr(0, v.length) == v;
+ },
+ "$=" : function(a, v){
+ return a && a.substr(a.length-v.length) == v;
+ },
+ "*=" : function(a, v){
+ return a && a.indexOf(v) !== -1;
+ },
+ "%=" : function(a, v){
+ return (a % v) == 0;
+ },
+ "|=" : function(a, v){
+ return a && (a == v || a.substr(0, v.length+1) == v+'-');
+ },
+ "~=" : function(a, v){
+ return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
+ }
+ },
+
+ /**
+ * Collection of "pseudo class" processors. Each processor is passed the current nodeset (array)
+ * and the argument (if any) supplied in the selector.
+ */
+ pseudos : {
+ "first-child" : function(c){
+ var r = [], ri = -1, n;
+ for(var i = 0, ci; ci = n = c[i]; i++){
+ while((n = n.previousSibling) && n.nodeType != 1);
+ if(!n){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "last-child" : function(c){
+ var r = [], ri = -1, n;
+ for(var i = 0, ci; ci = n = c[i]; i++){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ if(!n){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "nth-child" : function(c, a) {
+ var r = [], ri = -1;
+ var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
+ var f = (m[1] || 1) - 0, l = m[2] - 0;
+ for(var i = 0, n; n = c[i]; i++){
+ var pn = n.parentNode;
+ if (batch != pn._batch) {
+ var j = 0;
+ for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
+ if(cn.nodeType == 1){
+ cn.nodeIndex = ++j;
+ }
+ }
+ pn._batch = batch;
+ }
+ if (f == 1) {
+ if (l == 0 || n.nodeIndex == l){
+ r[++ri] = n;
+ }
+ } else if ((n.nodeIndex + l) % f == 0){
+ r[++ri] = n;
+ }
+ }
+
+ return r;
+ },
+
+ "only-child" : function(c){
+ var r = [], ri = -1;;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(!prev(ci) && !next(ci)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "empty" : function(c){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var cns = ci.childNodes, j = 0, cn, empty = true;
+ while(cn = cns[j]){
+ ++j;
+ if(cn.nodeType == 1 || cn.nodeType == 3){
+ empty = false;
+ break;
+ }
+ }
+ if(empty){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "contains" : function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "nodeValue" : function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(ci.firstChild && ci.firstChild.nodeValue == v){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "checked" : function(c){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(ci.checked == true){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "not" : function(c, ss){
+ return Ext.DomQuery.filter(c, ss, true);
+ },
+
+ "any" : function(c, selectors){
+ var ss = selectors.split('|');
+ var r = [], ri = -1, s;
+ for(var i = 0, ci; ci = c[i]; i++){
+ for(var j = 0; s = ss[j]; j++){
+ if(Ext.DomQuery.is(ci, s)){
+ r[++ri] = ci;
+ break;
+ }
+ }
+ }
+ return r;
+ },
+
+ "odd" : function(c){
+ return this["nth-child"](c, "odd");
+ },
+
+ "even" : function(c){
+ return this["nth-child"](c, "even");
+ },
+
+ "nth" : function(c, a){
+ return c[a-1] || [];
+ },
+
+ "first" : function(c){
+ return c[0] || [];
+ },
+
+ "last" : function(c){
+ return c[c.length-1] || [];
+ },
+
+ "has" : function(c, ss){
+ var s = Ext.DomQuery.select;
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(s(ss, ci).length > 0){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "next" : function(c, ss){
+ var is = Ext.DomQuery.is;
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = next(ci);
+ if(n && is(n, ss)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "prev" : function(c, ss){
+ var is = Ext.DomQuery.is;
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = prev(ci);
+ if(n && is(n, ss)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ }
+ }
+ };
+}();
+
+Ext.query = Ext.DomQuery.select;
+
+Date.precompileFormats = function(s){
+ var formats = s.split('|');
+ for(var i = 0, len = formats.length;i < len;i++){
+ Date.createNewFormat(formats[i]);
+ Date.createParser(formats[i]);
+ }
+}
+
+Date.precompileFormats("D n/j/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|YmdHis|F d, Y|l, F d, Y|H:i:s|g:i A|g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|m/d/y|m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|Y-m-d H:i:s|d/m/y|d/m/Y|d-m-y|d-m-Y|d/m|d-m|dm|dmy|dmY|Y-m-d|l|D m/d|D m/d/Y|m/d/Y");
+
+// precompile instead of lazy init
+Ext.ColorPalette.prototype.tpl = new Ext.XTemplate(
+ ' '
+);
+
+
+
+
+
diff --git a/thirdpartyjs/extjs/air/src/sql/AirConnection.js b/thirdpartyjs/extjs/air/src/sql/AirConnection.js
new file mode 100644
index 0000000..c78e9c2
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/sql/AirConnection.js
@@ -0,0 +1,86 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+ Ext.sql.AirConnection = Ext.extend(Ext.sql.Connection, {
+ // abstract methods
+ open : function(db){
+ this.conn = new air.SQLConnection();
+ var file = air.File.applicationDirectory.resolvePath(db);
+ this.conn.open(file);
+ this.openState = true;
+ this.fireEvent('open', this);
+ },
+
+ close : function(){
+ this.conn.close();
+ this.fireEvent('close', this);
+ },
+
+ createStatement : function(type){
+ var stmt = new air.SQLStatement();
+ stmt.sqlConnection = this.conn;
+ return stmt;
+ },
+
+ exec : function(sql){
+ var stmt = this.createStatement('exec');
+ stmt.text = sql;
+ stmt.execute();
+ },
+
+ execBy : function(sql, args){
+ var stmt = this.createStatement('exec');
+ stmt.text = sql;
+ this.addParams(stmt, args);
+ stmt.execute();
+ },
+
+ query : function(sql){
+ var stmt = this.createStatement('query');
+ stmt.text = sql;
+ stmt.execute(this.maxResults);
+ return this.readResults(stmt.getResult());
+ },
+
+ queryBy : function(sql, args){
+ var stmt = this.createStatement('query');
+ stmt.text = sql;
+ this.addParams(stmt, args);
+ stmt.execute(this.maxResults);
+ return this.readResults(stmt.getResult());
+ },
+
+ addParams : function(stmt, args){
+ if(!args){ return; }
+ for(var key in args){
+ if(args.hasOwnProperty(key)){
+ if(!isNaN(key)){
+ var v = args[key];
+ if(Ext.isDate(v)){
+ v = v.format(Ext.sql.Proxy.DATE_FORMAT);
+ }
+ stmt.parameters[parseInt(key)] = v;
+ }else{
+ stmt.parameters[':' + key] = args[key];
+ }
+ }
+ }
+ return stmt;
+ },
+
+ readResults : function(rs){
+ var r = [];
+ if(rs && rs.data){
+ var len = rs.data.length;
+ for(var i = 0; i < len; i++) {
+ r[r.length] = rs.data[i];
+ }
+ }
+ return r;
+ }
+});
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/sql/Connection.js b/thirdpartyjs/extjs/air/src/sql/Connection.js
new file mode 100644
index 0000000..746a74c
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/sql/Connection.js
@@ -0,0 +1,98 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+// Asbtract base class for Connection classes
+Ext.sql.Connection = function(config){
+ Ext.apply(this, config);
+ Ext.sql.Connection.superclass.constructor.call(this);
+
+ this.addEvents({
+ open : true,
+ close: true
+ });
+};
+
+Ext.extend(Ext.sql.Connection, Ext.util.Observable, {
+ maxResults: 10000,
+ openState : false,
+
+ // abstract methods
+ open : function(file){
+ },
+
+ close : function(){
+ },
+
+ exec : function(sql){
+ },
+
+ execBy : function(sql, args){
+ },
+
+ query : function(sql){
+ },
+
+ queryBy : function(sql, args){
+ },
+
+ // protected/inherited method
+ isOpen : function(){
+ return this.openState;
+ },
+
+ getTable : function(name, keyName){
+ return new Ext.sql.Table(this, name, keyName);
+ },
+
+ createTable : function(o){
+ var tableName = o.name;
+ var keyName = o.key;
+ var fs = o.fields;
+ if(!Ext.isArray(fs)){ // Ext fields collection
+ fs = fs.items;
+ }
+ var buf = [];
+ for(var i = 0, len = fs.length; i < len; i++){
+ var f = fs[i], s = f.name;
+ switch(f.type){
+ case "int":
+ case "bool":
+ case "boolean":
+ s += ' INTEGER';
+ break;
+ case "float":
+ s += ' REAL';
+ break;
+ default:
+ s += ' TEXT';
+ }
+ if(f.allowNull === false || f.name == keyName){
+ s += ' NOT NULL';
+ }
+ if(f.name == keyName){
+ s += ' PRIMARY KEY';
+ }
+ if(f.unique === true){
+ s += ' UNIQUE';
+ }
+
+ buf[buf.length] = s;
+ }
+ var sql = ['CREATE TABLE IF NOT EXISTS ', tableName, ' (', buf.join(','), ')'].join('');
+ this.exec(sql);
+ }
+});
+
+
+Ext.sql.Connection.getInstance = function(db, config){
+ if(Ext.isAir){ // air
+ return new Ext.sql.AirConnection(config);
+ } else { // gears
+ return new Ext.sql.GearsConnection(config);
+ }
+};
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/sql/Proxy.js b/thirdpartyjs/extjs/air/src/sql/Proxy.js
new file mode 100644
index 0000000..8ceb82c
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/sql/Proxy.js
@@ -0,0 +1,100 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+Ext.sql.Proxy = function(conn, table, keyName, store, readonly){
+ Ext.sql.Proxy.superclass.constructor.call(this);
+ this.conn = conn;
+ this.table = this.conn.getTable(table, keyName);
+ this.store = store;
+
+ if (readonly !== true) {
+ this.store.on('add', this.onAdd, this);
+ this.store.on('update', this.onUpdate, this);
+ this.store.on('remove', this.onRemove, this);
+ }
+};
+
+Ext.sql.Proxy.DATE_FORMAT = 'Y-m-d H:i:s';
+
+Ext.extend(Ext.sql.Proxy, Ext.data.DataProxy, {
+ load : function(params, reader, callback, scope, arg){
+ if(!this.conn.isOpen()){ // assume that the connection is in the process of opening
+ this.conn.on('open', function(){
+ this.load(params, reader, callback, scope, arg);
+ }, this, {single:true});
+ return;
+ };
+ if(this.fireEvent("beforeload", this, params, reader, callback, scope, arg) !== false){
+ var clause = params.where || '';
+ var args = params.args || [];
+ var group = params.groupBy;
+ var sort = params.sort;
+ var dir = params.dir;
+
+ if(group || sort){
+ clause += ' ORDER BY ';
+ if(group && group != sort){
+ clause += group + ' ASC, ';
+ }
+ clause += sort + ' ' + (dir || 'ASC');
+ }
+
+ var rs = this.table.selectBy(clause, args);
+ this.onLoad({callback:callback, scope:scope, arg:arg, reader: reader}, rs);
+ }else{
+ callback.call(scope||this, null, arg, false);
+ }
+ },
+
+ onLoad : function(trans, rs, e, stmt){
+ if(rs === false){
+ this.fireEvent("loadexception", this, null, trans.arg, e);
+ trans.callback.call(trans.scope||window, null, trans.arg, false);
+ return;
+ }
+ var result = trans.reader.readRecords(rs);
+ this.fireEvent("load", this, rs, trans.arg);
+ trans.callback.call(trans.scope||window, result, trans.arg, true);
+ },
+
+ processData : function(o){
+ var fs = this.store.fields;
+ var r = {};
+ for(var key in o){
+ var f = fs.key(key), v = o[key];
+ if(f){
+ if(f.type == 'date'){
+ r[key] = v ? v.format(Ext.sql.Proxy.DATE_FORMAT,10) : '';
+ }else if(f.type == 'boolean'){
+ r[key] = v ? 1 : 0;
+ }else{
+ r[key] = v;
+ }
+ }
+ }
+ return r;
+ },
+
+ onUpdate : function(ds, record){
+ var changes = record.getChanges();
+ var kn = this.table.keyName;
+ this.table.updateBy(this.processData(changes), kn + ' = ?', [record.data[kn]]);
+ record.commit(true);
+ },
+
+ onAdd : function(ds, records, index){
+ for(var i = 0, len = records.length; i < len; i++){
+ this.table.insert(this.processData(records[i].data));
+ }
+ },
+
+ onRemove : function(ds, record, index){
+ var kn = this.table.keyName;
+ this.table.removeBy(kn + ' = ?', [record.data[kn]]);
+ }
+});
\ No newline at end of file
diff --git a/thirdpartyjs/extjs/air/src/sql/Table.js b/thirdpartyjs/extjs/air/src/sql/Table.js
new file mode 100644
index 0000000..0f47f68
--- /dev/null
+++ b/thirdpartyjs/extjs/air/src/sql/Table.js
@@ -0,0 +1,94 @@
+/*
+ * Ext JS Library 0.20
+ * Copyright(c) 2006-2008, Ext JS, LLC.
+ * licensing@extjs.com
+ *
+ * http://extjs.com/license
+ */
+
+Ext.sql.Table = function(conn, name, keyName){
+ this.conn = conn;
+ this.name = name;
+ this.keyName = keyName;
+};
+
+Ext.sql.Table.prototype = {
+ update : function(o){
+ var clause = this.keyName + " = ?";
+ return this.updateBy(o, clause, [o[this.keyName]]);
+ },
+
+ updateBy : function(o, clause, args){
+ var sql = "UPDATE " + this.name + " set ";
+ var fs = [], a = [];
+ for(var key in o){
+ if(o.hasOwnProperty(key)){
+ fs[fs.length] = key + ' = ?';
+ a[a.length] = o[key];
+ }
+ }
+ for(var key in args){
+ if(args.hasOwnProperty(key)){
+ a[a.length] = args[key];
+ }
+ }
+ sql = [sql, fs.join(','), ' WHERE ', clause].join('');
+ return this.conn.execBy(sql, a);
+ },
+
+ insert : function(o){
+ var sql = "INSERT into " + this.name + " ";
+ var fs = [], vs = [], a = [];
+ for(var key in o){
+ if(o.hasOwnProperty(key)){
+ fs[fs.length] = key;
+ vs[vs.length] = '?';
+ a[a.length] = o[key];
+ }
+ }
+ sql = [sql, '(', fs.join(','), ') VALUES (', vs.join(','), ')'].join('');
+ return this.conn.execBy(sql, a);
+ },
+
+ lookup : function(id){
+ return this.selectBy('where ' + this.keyName + " = ?", [id])[0] || null;
+ },
+
+ exists : function(id){
+ return !!this.lookup(id);
+ },
+
+ save : function(o){
+ if(this.exists(o[this.keyName])){
+ this.update(o);
+ }else{
+ this.insert(o);
+ }
+ },
+
+ select : function(clause){
+ return this.selectBy(clause, null);
+ },
+
+ selectBy : function(clause, args){
+ var sql = "select * from " + this.name;
+ if(clause){
+ sql += ' ' + clause;
+ }
+ args = args || {};
+ return this.conn.queryBy(sql, args);
+ },
+
+ remove : function(clause){
+ this.deleteBy(clause, null);
+ },
+
+ removeBy : function(clause, args){
+ var sql = "delete from " + this.name;
+ if(clause){
+ sql += ' where ' + clause;
+ }
+ args = args || {};
+ this.conn.execBy(sql, args);
+ }
+};
\ No newline at end of file