window.ajax =
  {
    //REQUESTS&RESPONSES ARRAY: BEGIN
    items : [],
    //REQUESTS&RESPONSES ARRAY: END

    //RANDOM: BEGIN
    random : function(from, to)
      {
        from = parseInt(from);
        to = parseInt(to);

        return String(Math.floor(Math.random() * (to - from + 1)) + from);
      },
    //RANDOM: END

    //ATTACH EVENT: BEGIN
    eventAdd : function(element, event, action)
      {
             if (element.addEventListener) return element.addEventListener(event.substr(2).toLowerCase(), action, false);
        else if (element.attachEvent)      return element.attachEvent(event, action);
        else                               return element[event] = action;
      },
    //ATTACH EVENT: END

    //REQUEST: BEGIN
    request : function(url, method, vars)
      {
        this.items = [];
        do { //GENERATE UNIQUE 6-DIGIT ID
             var id = String(this.random(100000, 999999));
           } while (typeof(this.items[id]) == "object");

        this.jaf(id, url, method, vars);
        return id;
      },
    //REQUEST: END

    //RESPONSE: BEGIN
    response : function(id)
      {
        return (this.items[id]?this.json.decode(this.items[id]):false);
      },
    //RESPONSE: END

    //JAF: BEGIN
    jaf : function(id, url, method, vars)
      {
        var iframe = document.createElement("iframe");
        iframe.style.display = "none"; iframe.width = iframe.height = iframe.frameborder = 0;
        iframe.name = "__name__tmp_iframe_for_jaf_submit_id" + id;
        document.body.appendChild(iframe);

        this.eventAdd(iframe, "onload", function()
                                          {
                                            if (iframe.contentWindow.document.body.innerHTML.length > 0)
                                              {
                                                ajax.items[id] = iframe.contentWindow.document.body.innerHTML;
                                                iframe.contentWindow.document.body.innerHTML = '';
                                              }

                                            return iframe.removeNode;
                                          });

        return this.load(url, method, vars, iframe);
      },
    //JAF: END

    //LOAD: BEGIN
    load : function(url, method, vars, target)
      {
        var iform = document.createElement("form");
        iform.action = url;
        iform.method = method ? method : "GET";
             if (typeof(target) == "object") iform.target = target.contentWindow.name = target.name;
        else if (typeof(target) == "string") iform.target = target;
        else                                 iform.target = "_self"; //OR "_top" OR "_blank"

        for (var parameter in vars)
          {
            input = document.createElement("input");
            input.type = "hidden";
            input.name = parameter;
            input.value = vars[parameter];
            iform.appendChild(input);
          }
        document.body.appendChild(iform);
        iform.submit();
        iform.removeNode;

        return true;
      },
    //LOAD: END

    //JSON: BEGIN
    json :
      {
        debackslashify : function(text)
          {
            return text.replace(/\\(?:u(.{4})|([^u]))/g, function (a, b, c) { return b ? String.fromCharCode(parseInt(b, 16)) : escapes[c]; });
          },

        decode : function (source)
          {
            var state,
                stack,
                container,
                key,
                value,
                escapes = {'\\': '\\', '"': '"', '/': '/', 't': '\t', 'n': '\n', 'r': '\r', 'f': '\f', 'b': '\b'},
                string =
                  {
                    go: function () { state = 'ok'; },
                    firstokey: function () { key = value; state = 'colon'; },
                    okey: function () { key = value; state = 'colon'; },
                    ovalue: function () { state = 'ocomma'; },
                    firstavalue: function () { state = 'acomma'; },
                    avalue: function () { state = 'acomma'; }
                  },
                number =
                  {
                    go: function () { state = 'ok'; },
                    ovalue: function () { state = 'ocomma'; },
                    firstavalue: function () { state = 'acomma'; },
                    avalue: function () { state = 'acomma'; }
                  },
                action =
                  {
                    '{':
                      {
                        go: function () { stack.push({state: 'ok'}); container = {}; state = 'firstokey'; },
                        ovalue: function () { stack.push({container: container, state: 'ocomma', key: key}); container = {}; state = 'firstokey'; },
                        firstavalue: function () { stack.push({container: container, state: 'acomma'}); container = {}; state = 'firstokey'; },
                        avalue: function () { stack.push({container: container, state: 'acomma'}); container = {}; state = 'firstokey'; }
                      },
                    '}':
                      {
                        firstokey: function () { var pop = stack.pop(); value = container; container = pop.container; key = pop.key; state = pop.state; },
                        ocomma: function () { var pop = stack.pop(); container[key] = value; value = container; container = pop.container; key = pop.key; state = pop.state; }
                      },
                    '[':
                      {
                        go: function () { stack.push({state: 'ok'}); container = []; state = 'firstavalue'; },
                        ovalue: function () { stack.push({container: container, state: 'ocomma', key: key}); container = []; state = 'firstavalue'; },
                        firstavalue: function () { stack.push({container: container, state: 'acomma'}); container = []; state = 'firstavalue'; },
                        avalue: function () { stack.push({container: container, state: 'acomma'}); container = []; state = 'firstavalue'; }
                      },
                    ']':
                      {
                        firstavalue: function () { var pop = stack.pop(); value = container; container = pop.container; key = pop.key; state = pop.state; },
                        acomma: function () { var pop = stack.pop(); container.push(value); value = container; container = pop.container; key = pop.key; state = pop.state; }
                      },
                    ':':
                      {
                        colon: function () { if (Object.hasOwnProperty.call(container, key)) { throw new SyntaxError('Duplicate key "' + key + '"'); } state = 'ovalue'; }
                      },
                    ',':
                      {
                        ocomma: function () { container[key] = value; state = 'okey'; },
                        acomma: function () { container.push(value); state = 'avalue'; }
                      },
                    'true':
                      {
                        go: function () { value = true; state = 'ok'; },
                        ovalue: function () { value = true; state = 'ocomma'; },
                        firstavalue: function () { value = true; state = 'acomma'; },
                        avalue: function () { value = true; state = 'acomma'; }
                      },
                    'false':
                      {
                        go: function () { value = false; state = 'ok'; },
                        ovalue: function () { value = false; state = 'ocomma'; },
                        firstavalue: function () { value = false; state = 'acomma'; },
                        avalue: function () { value = false; state = 'acomma'; }
                      },
                    'null':
                      {
                        go: function () { value = null; state = 'ok'; },
                        ovalue: function () { value = null; state = 'ocomma'; },
                        firstavalue: function () { value = null; state = 'acomma'; },
                        avalue: function () { value = null; state = 'acomma'; }
                      }
                  };

            var r, tx = /^[\x20\t\n\r]*(?:([,:\[\]{}]|true|false|null)|(-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)|"((?:[^\r\n\t\\\"]|\\(?:["\\\/trnfb]|u[0-9a-fA-F]{4}))*)")/;
            state = 'go';
            stack = [];
            try
              {
                for (;;)
                  {
                    r = tx.exec(source);
                    if (!r) break;
                    if (r[1])
                      {
                        action[r[1]][state]();
                      }
                    else if (r[2])
                      {
                        value = +r[2];
                        number[state]();
                      }
                    else
                      {
                        value = this.debackslashify(r[3]);
                        string[state]();
                      }
                    source = source.slice(r[0].length);
                  }
              }
            catch (e)
              {
                state = e;
              }

            if (state !== 'ok' || /[^\x20\t\n\r]/.test(source))
              {
                throw state instanceof SyntaxError ? state : new SyntaxError('JSON');
              }

            return value;
          }
      }
  }