text: /*
   * Copyright (c) 2014 Chukong Technologies Inc.
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   * THE SOFTWARE.
   */
  
  //
  // cocos2d boot
  //
  
  var cc = cc || {};
  var window = window || this;
  
  /**
   * Iterate over an object or an array, executing a function for each matched element.
   * @param {object|array} obj
   * @param {function} iterator
   * @param [{object}] context
   */
  cc.each = function(obj, iterator, context){
      if(!obj) return;
      if(obj instanceof Array){
          for(var i = 0, li = obj.length; i < li; i++){
              if(iterator.call(context, obj[i], i) === false) return;
          }
      }else{
          for (var key in obj) {
              if(iterator.call(context, obj[key], key) === false) return;
          }
      }
  };
  
  /**
   * Common getter setter configuration function
   * @function
   * @param {Object}   proto      A class prototype or an object to config
   * @param {String}   prop       Property name
   * @param {function} getter     Getter function for the property
   * @param {function} setter     Setter function for the property
   */
  cc.defineGetterSetter = function (proto, prop, getter, setter){
      var desc = { enumerable: false, configurable: true };
      getter && (desc.get = getter);
      setter && (desc.set = setter);
      Object.defineProperty(proto, prop, desc);
  };
  
  //+++++++++++++++++++++++++something about async begin+++++++++++++++++++++++++++++++
  /**
   * Async Pool class, a helper of cc.async
   * @param {Object|Array} srcObj
   * @param {Number} limit the limit of parallel number
   * @param {function} iterator
   * @param {function} onEnd
   * @param {object} target
   * @constructor
   */
  cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){
      var self = this;
      self._srcObj = srcObj;
      self._limit = limit;
      self._pool = [];
      self._iterator = iterator;
      self._iteratorTarget = target;
      self._onEnd = onEnd;
      self._onEndTarget = target;
      self._results = srcObj instanceof Array ? [] : {};
      self._isErr = false;
  
      cc.each(srcObj, function(value, index){
          self._pool.push({index : index, value : value});
      });
  
      self.size = self._pool.length;
      self.finishedSize = 0;
      self._workingSize = 0;
  
      self._limit = self._limit || self.size;
  
      self.onIterator = function(iterator, target){
          self._iterator = iterator;
          self._iteratorTarget = target;
      };
  
      self.onEnd = function(endCb, endCbTarget){
          self._onEnd = endCb;
          self._onEndTarget = endCbTarget;
      };
  
      self._handleItem = function(){
          var self = this;
          if(self._pool.length == 0)
              return;                                                         //return directly if the array's length = 0
          if(self._workingSize >= self._limit)
              return;                                                         //return directly if the working size great equal limit number
          var item = self._pool.shift();
          var value = item.value, index = item.index;
          self._workingSize++;
          self._iterator.call(self._iteratorTarget, value, index, function(err){
              if(self._isErr)
                  return;
  
              self.finishedSize++;
              self._workingSize--;
              if(err) {
                  self._isErr = true;
                  if(self._onEnd)
                      self._onEnd.call(self._onEndTarget, err);
                  return
              }
  
              var arr = Array.prototype.slice.call(arguments, 1);
              self._results[this.index] = arr[0];
              if(self.finishedSize == self.size) {
                  if(self._onEnd)
                      self._onEnd.call(self._onEndTarget, null, self._results);
                  return;
              }
              self._handleItem();
          }.bind(item), self);
      };
  
      self.flow = function(){
          var self = this;
          if(self._pool.length == 0) {
              if(self._onEnd)
                  self._onEnd.call(self._onEndTarget, null, []);
              return;
          }
          for(var i = 0; i < self._limit; i++)
              self._handleItem();
      }
  };
  
  cc.async = {
      /**
       * Do tasks series.
       * @param {Array|Object} tasks
       * @param {function} [cb] callback
       * @param {Object} [target]
       * @return {cc.AsyncPool}
       */
      series : function(tasks, cb, target){
          var asyncPool = new cc.AsyncPool(tasks, 1, function(func, index, cb1){
              func.call(target, cb1);
          }, cb, target);
          asyncPool.flow();
          return asyncPool;
      },
  
      /**
       * Do tasks parallel.
       * @param {Array|Object} tasks
       * @param {function} cb callback
       * @param {Object} [target]
       * @return {cc.AsyncPool}
       */
      parallel : function(tasks, cb, target){
          var asyncPool = new cc.AsyncPool(tasks, 0, function(func, index, cb1){
              func.call(target, cb1);
          }, cb, target);
          asyncPool.flow();
          return asyncPool;
      },
  
      /**
       * Do tasks waterfall.
       * @param {Array|Object} tasks
       * @param {function} cb callback
       * @param {Object} [target]
       * @return {cc.AsyncPool}
       */
      waterfall : function(tasks, cb, target){
          var args = [];
          var asyncPool = new cc.AsyncPool(tasks, 1,
              function (func, index, cb1) {
                  args.push(function (err) {
                      args = Array.prototype.slice.call(arguments, 1);
                      cb1.apply(null, arguments);
                  });
                  func.apply(target, args);
              }, function (err, results) {
                  if (!cb)
                      return;
                  if (err)
                      return cb.call(target, err);
                  cb.call(target, null, results[results.length - 1]);
              });
          asyncPool.flow();
          return asyncPool;
      },
  
      /**
       * Do tasks by iterator.
       * @param {Array|Object} tasks
       * @param {function|Object} iterator
       * @param {function} cb callback
       * @param {Object} [target]
       * @return {cc.AsyncPool}
       */
      map : function(tasks, iterator, cb, target){
          var locIterator = iterator;
          if(typeof(iterator) == "object"){
              cb = iterator.cb;
              target = iterator.iteratorTarget;
              locIterator = iterator.iterator;
          }
          var asyncPool = new cc.AsyncPool(tasks, 0, locIterator, cb, target);
          asyncPool.flow();
          return asyncPool;
      },
  
      /**
       * Do tasks by iterator limit.
       * @param {Array|Object} tasks
       * @param {Number} limit
       * @param {function} iterator
       * @param {function} cb callback
       * @param {Object} [target]
       */
      mapLimit : function(tasks, limit, iterator, cb, target){
          var asyncPool = new cc.AsyncPool(tasks, limit, iterator, cb, target);
          asyncPool.flow();
          return asyncPool;
      }
  };
  //+++++++++++++++++++++++++something about async end+++++++++++++++++++++++++++++++++
  
  //+++++++++++++++++++++++++something about path begin++++++++++++++++++++++++++++++++
  cc.path = {
      /**
       * Join strings to be a path.
       * @example
       cc.path.join("a", "b.png");//-->"a/b.png"
       cc.path.join("a", "b", "c.png");//-->"a/b/c.png"
       cc.path.join("a", "b");//-->"a/b"
       cc.path.join("a", "b", "/");//-->"a/b/"
       cc.path.join("a", "b/", "/");//-->"a/b/"
       * @returns {string}
       */
      join : function(){
          var l = arguments.length;
          var result = "";
          for(var i = 0; i < l; i++) {
              result = (result + (result == "" ? "" : "/") + arguments[i]).replace(/(\/|\\\\)$/, "");
          }
          return result;
      },
      
      /**
       * Get the ext name of a path.
       * @example
       cc.path.extname("a/b.png");//-->".png"
       cc.path.extname("a/b.png?a=1&b=2");//-->".png"
       cc.path.extname("a/b");//-->null
       cc.path.extname("a/b?a=1&b=2");//-->null
       * @param pathStr
       * @returns {*}
       */
      extname : function(pathStr){
          var index = pathStr.indexOf("?");
          if(index > 0) pathStr = pathStr.substring(0, index);
          index = pathStr.lastIndexOf(".");
          if(index < 0) return null;
          return pathStr.substring(index, pathStr.length);
      },
      
      /**
       * Get the file name of a file path.
       * @example
       cc.path.basename("a/b.png");//-->"b.png"
       cc.path.basename("a/b.png?a=1&b=2");//-->"b.png"
       cc.path.basename("a/b.png", ".png");//-->"b"
       cc.path.basename("a/b.png?a=1&b=2", ".png");//-->"b"
       cc.path.basename("a/b.png", ".txt");//-->"b.png"
       * @param pathStr
       * @param extname
       * @returns {*}
       */
      basename : function(pathStr, extname){
          var index = pathStr.indexOf("?");
          if(index > 0) pathStr = pathStr.substring(0, index);
          var reg = /(\/|\\\\)([^(\/|\\\\)]+)$/g;
          var result = reg.exec(pathStr.replace(/(\/|\\\\)$/, ""));
          if(!result) return null;
          var baseName = result[2];
          if(extname && pathStr.substring(pathStr.length - extname.length).toLowerCase() == extname.toLowerCase())
              return baseName.substring(0, baseName.length - extname.length);
          return baseName;
      },
      
      /**
       * Get ext name of a file path.
       * @example
       cc.path.driname("a/b/c.png");//-->"a/b"
       cc.path.driname("a/b/c.png?a=1&b=2");//-->"a/b"
       * @param {String} pathStr
       * @returns {*}
       */
      dirname : function(pathStr){
          return pathStr.replace(/(\/|\\\\)$/, "").replace(/(\/|\\\\)[^(\/|\\\\)]+$/, "");
      },
      
      /**
       * Change extname of a file path.
       * @example
       cc.path.changeExtname("a/b.png", ".plist");//-->"a/b.plist"
       cc.path.changeExtname("a/b.png?a=1&b=2", ".plist");//-->"a/b.plist?a=1&b=2"
       * @param pathStr
       * @param extname
       * @returns {string}
       */
      changeExtname : function(pathStr, extname){
          extname = extname || "";
          var index = pathStr.indexOf("?");
          var tempStr = "";
          if(index > 0) {
              tempStr = pathStr.substring(index);
              pathStr = pathStr.substring(0, index);
          };
          index = pathStr.lastIndexOf(".");
          if(index < 0) return pathStr + extname + tempStr;
          return pathStr.substring(0, index) + extname + tempStr;
      },
      /**
       * Change file name of a file path.
       * @example
       cc.path.changeBasename("a/b/c.plist", "b.plist");//-->"a/b/b.plist"
       cc.path.changeBasename("a/b/c.plist?a=1&b=2", "b.plist");//-->"a/b/b.plist?a=1&b=2"
       cc.path.changeBasename("a/b/c.plist", ".png");//-->"a/b/c.png"
       cc.path.changeBasename("a/b/c.plist", "b");//-->"a/b/b"
       cc.path.changeBasename("a/b/c.plist", "b", true);//-->"a/b/b.plist"
       * @param {String} pathStr
       * @param {String} basename
       * @param [{Boolean}] isSameExt
       * @returns {string}
       */
      changeBasename : function(pathStr, basename, isSameExt){
          if(basename.indexOf(".") == 0) return this.changeExtname(pathStr, basename);
          var index = pathStr.indexOf("?");
          var tempStr = "";
          var ext = isSameExt ? this.extname(pathStr) : "";
          if(index > 0) {
              tempStr = pathStr.substring(index);
              pathStr = pathStr.substring(0, index);
          };
          index = pathStr.lastIndexOf("/");
          index = index <= 0 ? 0 : index+1;
          return pathStr.substring(0, index) + basename + ext + tempStr;
      }
  };
  //+++++++++++++++++++++++++something about path end++++++++++++++++++++++++++++++++
  
  //+++++++++++++++++++++++++something about loader start+++++++++++++++++++++++++++
  cc.loader = {
      _resPath : "",
      _audioPath : "",
      _register : {},//register of loaders
      cache : {},//cache for data loaded
      _langPathCache : {},//cache for lang path
      
      /**
       * Get XMLHttpRequest.
       * @returns {XMLHttpRequest}
       */
      getXMLHttpRequest : function () {
          return new XMLHttpRequest();
      },
      
      
      //@MODE_BEGIN DEV
      
      _jsCache : {},//cache for js
      
      _getArgs4Js : function(args){
          var a0 = args[0], a1 = args[1], a2 = args[2], results = ["", null, null];
          
          if(args.length == 1){
              results[1] = a0 instanceof Array ? a0 : [a0];
          }else if(args.length == 2){
              if(typeof a1 == "function"){
                  results[1] = a0 instanceof Array ? a0 : [a0];
                  results[2] = a1;
              }else{
                  results[0] = a0 || "";
                  results[1] = a1 instanceof Array ? a1 : [a1];
              }
          }else if(args.length == 3){
              results[0] = a0 || "";
              results[1] = a1 instanceof Array ? a1 : [a1];
              results[2] = a2;
          }else throw "arguments error to load js!";
          return results;
      },
      /**
       * Load js files.
       * @param {?string=} baseDir   The pre path for jsList.
       * @param {array.<string>} jsList    List of js path.
       * @param {function} cb        Callback function
       *
       *      If the arguments.length == 2, then the baseDir turns to be "".
       * @returns {*}
       */
      loadJs : function(baseDir, jsList, cb){
          var self = this, localJsCache = self._jsCache,
          args = self._getArgs4Js(arguments);
          baseDir = args[0];
          jsList = args[1];
          cb = args[2];
          var ccPath = cc.path;
          for(var i = 0, li = jsList.length; i < li; ++i){
              require(ccPath.join(baseDir, jsList[i]));
          }
          if(cb) cb();
      },
      /**
       * Load js width loading image.
       * @param {?string} baseDir
       * @param {array} jsList
       * @param {function} cb
       */
      loadJsWithImg : function(baseDir, jsList, cb){
          this.loadJs.apply(this, arguments);
      },
      
      //@MODE_END DEV
      
      /**
       * Load a single resource as txt.
       * @param {!string} url
       * @param {function} cb arguments are : err, txt
       */
      loadTxt : function(url, cb){
          cb(null, jsb.fileUtils.getStringFromFile(url));
      },
      
      loadJson : function(url, cb){
          this.loadTxt(url, function(err, txt){
              try{
                  err ? cb(err) : cb(null, JSON.parse(txt));
              }catch(e){
                  throw e;
                  cb("load json [" + url + "] failed : " + e);
              }
          });
      },
      
      /**
       * Load a single image.
       * @param {!string} url
       * @param [{object}] option
       * @param {function} cb
       * @returns {Image}
       */
      loadImg : function(url, option, cb){
          var l = arguments.length;
          if(l == 2) cb = option;
  
          var cachedTex = cc.textureCache.getTextureForKey(url);
          if (cachedTex) {
              cb && cb(null, cachedTex);
          }
          else if (url.match(jsb.urlRegExp)) {
              jsb.loadRemoteImg(url, function(succeed, tex) {
                  if (succeed) {
                      cb && cb(null, tex);
                  }
                  else {
                      cb && cb("Load image failed");
                  }
              });
          }
          else {
              var tex = cc.textureCache._addImage(url);
              if (tex instanceof cc.Texture2D)
                  cb && cb(null, tex);
              else cb && cb("Load image failed");
          }
      },
      /**
       * Load binary data by url.
       * @param {String} url
       * @param {Function} cb
       */
      loadBinary : function(url, cb){
          cb(null, jsb.fileUtils.getDataFromFile(url));
      },
      loadBinarySync : function(url){
          return jsb.fileUtils.getDataFromFile(url);
      },
      
      /**
       * Iterator function to load res
       * @param {object} item
       * @param {number} index
       * @param {function} cb
       * @returns {*}
       * @private
       */
      _loadResIterator : function(item, index, cb){
          var self = this, url = null;
          var type = item.type;
          if (type) {
              type = "." + type.toLowerCase();
              url = item.src ? item.src : item.name + type;
          } else {
              url = item;
              type = cc.path.extname(url);
          }
  
          var obj = self.cache[url];
          if (obj)
              return cb(null, obj);
          var loader = null;
          if (type) {
              loader = self._register[type.toLowerCase()];
          }
          if (!loader) {
              cc.error("loader for [" + type + "] not exists!");
              return cb();
          }
          var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
          var realUrl = self.getUrl(basePath, url);
          var data = loader.load(realUrl, url);
          if (data) {
              self.cache[url] = data;
              cb(null, data);
          } else {
              self.cache[url] = null;
              delete self.cache[url];
              cb();
          }
      },
      
      /**
       * Get url with basePath.
       * @param [{string}] basePath
       * @param {string} url
       * @returns {*}
       */
      getUrl : function(basePath, url){
          var self = this, langPathCache = self._langPathCache, path = cc.path;
          if(arguments.length == 1){
              url = basePath;
              var type = path.extname(url);
              type = type ? type.toLowerCase() : "";
              var loader = self._register[type];
              if(!loader)
                  basePath = self.resPath;
              else
                  basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
          }
          url = cc.path.join(basePath || "", url);
          if(url.match(/[\/(\\\\)]lang[\/(\\\\)]/i)){
              if(langPathCache[url])
                  return langPathCache[url];
              var extname = path.extname(url) || "";
              url = langPathCache[url] = url.substring(0, url.length - extname.length) + "_" + cc.sys.language + extname;
          }
          return url;
      },
      
      /**
       * Load resources then call the callback.
       * @param {[string]} res
       * @param [{function}|{}] option
       * @param {function} cb :
       */
      load : function(resources, option, cb){
          var self = this;
          var len = arguments.length;
          if(len == 0)
              throw "arguments error!";
  
          if(len == 3){
              if(typeof option == "function"){
                  if(typeof cb == "function")
                      option = {trigger : option, cb : cb };
                  else
                      option = { cb : option, cbTarget : cb};
              }
          }else if(len == 2){
              if(typeof option == "function")
                  option = {cb : option};
          }else if(len == 1){
              option = {};
          }
  
          if(!(resources instanceof Array))
              resources = [resources];
          var asyncPool = new cc.AsyncPool(resources, 0, function(value, index, cb1, aPool){
              self._loadResIterator(value, index, function(err){
                  if(err)
                      return cb1(err);
                  var arr = Array.prototype.slice.call(arguments, 1);
                  if(option.trigger)
                      option.trigger.call(option.triggerTarget, arr[0], aPool.size, aPool.finishedSize); //call trigger
                  cb1(null, arr[0]);
              });
          }, option.cb, option.cbTarget);
          asyncPool.flow();
          return asyncPool;
      },
  
      /**
       * <p>
       *     Loads alias map from the contents of a filename.                                        <br/>
       *                                                                                                                 <br/>
       *     @note The plist file name should follow the format below:                                                   <br/>
       *     <?xml version="1.0" encoding="UTF-8"?>                                                                      <br/>
       *         <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  <br/>
       *             <plist version="1.0">                                                                               <br/>
       *                 <dict>                                                                                          <br/>
       *                     <key>filenames</key>                                                                        <br/>
       *                     <dict>                                                                                      <br/>
       *                         <key>sounds/click.wav</key>                                                             <br/>
       *                         <string>sounds/click.caf</string>                                                       <br/>
       *                         <key>sounds/endgame.wav</key>                                                           <br/>
       *                         <string>sounds/endgame.caf</string>                                                     <br/>
       *                         <key>sounds/gem-0.wav</key>                                                             <br/>
       *                         <string>sounds/gem-0.caf</string>                                                       <br/>
       *                     </dict>                                                                                     <br/>
       *                     <key>metadata</key>                                                                         <br/>
       *                     <dict>                                                                                      <br/>
       *                         <key>version</key>                                                                      <br/>
       *                         <integer>1</integer>                                                                    <br/>
       *                     </dict>                                                                                     <br/>
       *                 </dict>                                                                                         <br/>
       *              </plist>                                                                                           <br/>
       * </p>
       * @param {String} filename  The plist file name.
       * @param {Function} cb     callback
       */
      loadAliases : function(url, cb){
          jsb.fileUtils.loadFilenameLookup(url);
          if(cb) cb();
      },
  
      /**
       * Register a resource loader into loader.
       * @param {string} extname
       * @param {load : function} loader
       */
      register : function(extNames, loader){
          if(!extNames || !loader) return;
          var self = this;
          if(typeof extNames == "string")
              return this._register[extNames.trim().toLowerCase()] = loader;
          for(var i = 0, li = extNames.length; i < li; i++) {
              self._register["." + extNames[i].trim().toLowerCase()] = loader;
          }
      },
      
      /**
       * Get resource data by url.
       * @param url
       * @returns {*}
       */
      getRes : function(url){
          var cached = this.cache[url];
          if (cached)
              return cached;
          var type = cc.path.extname(url);
          var loader = this._register[type.toLowerCase()];
          if(!loader) return cc.log("loader for [" + type + "] not exists!");
          var basePath = loader.getBasePath ? loader.getBasePath() : this.resPath;
          var realUrl = this.getUrl(basePath, url);
          return loader.load(realUrl, url);
      },
      
      /**
       * Release the cache of resource by url.
       * @param url
       */
      release : function(url){//do nothing in jsb
      },
      
      /**
       * Resource cache of all resources.
       */
      releaseAll : function(){//do nothing in jsb
      }
      
  };
  cc.defineGetterSetter(cc.loader, "resPath", function(){
      return this._resPath;
  }, function(resPath){
      this._resPath = resPath || "";
      jsb.fileUtils.addSearchPath(this._resPath);
  });
  cc.defineGetterSetter(cc.loader, "audioPath", function(){
      return this._audioPath;
  }, function(audioPath){
      this._audioPath = audioPath || "";
      jsb.fileUtils.addSearchPath(this._audioPath);
  });
  
  //+++++++++++++++++++++++++something about loader end+++++++++++++++++++++++++++++
  
  //+++++++++++++++++++++++++something about format string begin+++++++++++++++++++++++++++++
  
  /**
   * A string tool to construct a string with format string.
   * for example: cc.formatStr("a: %d, b: %b", a, b);
   * @param {String} formatStr format String
   * @returns {String}
   */
  cc.formatStr = function(){
      var args = arguments;
      var l = args.length;
      if(l < 1)
          return "";
  
      var str = args[0];
      var needToFormat = true;
      if(typeof str == "object"){
          needToFormat = false;
      }
      for(var i = 1; i < l; ++i){
          var arg = args[i];
          if(needToFormat){
              while(true){
                  var result = null;
                  if(typeof arg == "number"){
                      result = str.match(/(%d)|(%s)/);
                      if(result){
                          str = str.replace(/(%d)|(%s)/, arg);
                          break;
                      }
                  }
                  result = str.match(/%s/);
                  if(result)
                      str = str.replace(/%s/, arg);
                  else
                      str += "    " + arg;
                  break;
              }
          }else
              str += "    " + arg;
      }
      return str;
  };
  
  //+++++++++++++++++++++++Define singleton format string end+++++++++++++++++++++++++++
  
  //+++++++++++++++++++++++Define singleton objects begin+++++++++++++++++++++++++++
  
  // Define singleton objects
  /**
   * @type {cc.Director}
   * @name cc.director
   */
  cc.director = cc.Director.getInstance();
  /**
   * @type {cc.Size}
   * @name cc.winSize
   * cc.winSize is the alias object for the size of the current game window.
   */
  cc.winSize = cc.director.getWinSize();
  /**
   * @type {cc.EGLView}
   * @name cc.view
   * cc.view is the shared view object.
   */
  cc.view = cc.director.getOpenGLView();
  cc.view.getDevicePixelRatio = function () {
      var sys = cc.sys;
      return (sys.os == sys.OS_IOS || sys.os == sys.OS_OSX) ? 2 : 1;
  };
  cc.view.convertToLocationInView = function (tx, ty, relatedPos) {
      var _devicePixelRatio = cc.view.getDevicePixelRatio();
      return {x: _devicePixelRatio * (tx - relatedPos.left), y: _devicePixelRatio * (relatedPos.top + relatedPos.height - ty)};
  };
  cc.view.enableRetina = function(enabled) {};
  cc.view.isRetinaEnabled = function() {
      var sys = cc.sys;
      return (sys.os == sys.OS_IOS || sys.os == sys.OS_OSX) ? true : false;
  };
  cc.view.adjustViewPort = function() {};
  cc.view.resizeWithBrowserSize = function () {return;};
  cc.view.setResizeCallback = function() {return;};
  cc.view.enableAutoFullScreen = function () {return;};
  cc.view.isAutoFullScreenEnabled = function() {return true;};
  cc.view._setDesignResolutionSize = cc.view.setDesignResolutionSize;
  cc.view.setDesignResolutionSize = function(width,height,resolutionPolicy){
      cc.view._setDesignResolutionSize(width,height,resolutionPolicy);
      cc.winSize = cc.director.getWinSize();
      cc.visibleRect.init();
  };
  cc.view.setResolutionPolicy = function(resolutionPolicy){
      var size = cc.view.getDesignResolutionSize();
      cc.view.setDesignResolutionSize(size.width,size.height,resolutionPolicy);
  };
  cc.view.setContentTranslateLeftTop = function(){return;};
  cc.view.getContentTranslateLeftTop = function(){return null;};
  cc.view.setFrameZoomFactor = function(){return;};
  cc.DENSITYDPI_DEVICE = "device-dpi";
  cc.DENSITYDPI_HIGH = "high-dpi";
  cc.DENSITYDPI_MEDIUM = "medium-dpi";
  cc.DENSITYDPI_LOW = "low-dpi";
  cc.view.setTargetDensityDPI = function() {};
  cc.view.getTargetDensityDPI = function() {return cc.DENSITYDPI_DEVICE;};
  
  /**
   * @type {Object}
   * @name cc.eventManager
   */
  cc.eventManager = cc.director.getEventDispatcher();
  /**
   * @type {cc.AudioEngine}
   * @name cc.audioEngine
   * A simple Audio Engine engine API.
   */
  cc.audioEngine = cc.AudioEngine.getInstance();
  cc.audioEngine.end = function(){
      this.stopMusic();
      this.stopAllEffects();
  };
  /**
   * @type {Object}
   * @name cc.configuration
   * cc.configuration contains some openGL variables
   */
  cc.configuration = cc.Configuration.getInstance();
  /**
   * @type {Object}
   * @name cc.textureCache
   * cc.textureCache is the global cache for cc.Texture2D
   */
  cc.textureCache = cc.director.getTextureCache();
  cc.TextureCache.prototype._addImage = cc.TextureCache.prototype.addImage;
  cc.TextureCache.prototype.addImage = function(url, cb, target) {
      var localTex = null;
      cc.loader.loadImg(url, function(err, tex) {
          if (err) tex = null;
          if (cb) {
              cb.call(target, tex);
          }
          localTex = tex;
      });
      return localTex;
  };
  /**
   * @type {Object}
   * @name cc.shaderCache
   * cc.shaderCache is a singleton object that stores manages GL shaders
   */
  cc.shaderCache = cc.ShaderCache.getInstance();
  /**
   * @type {Object}
   * @name cc.animationCache
   */
  cc.animationCache = cc.AnimationCache.getInstance();
  /**
   * @type {Object}
   * @name cc.spriteFrameCache
   */
  cc.spriteFrameCache = cc.SpriteFrameCache.getInstance();
  /**
   * @type {cc.PlistParser}
   * @name cc.plistParser
   * A Plist Parser
   */
  cc.plistParser = cc.PlistParser.getInstance();
  //cc.tiffReader;
  //cc.imeDispatcher;
  
  // File utils (Temporary, won't be accessible)
  cc.fileUtils = cc.FileUtils.getInstance();
  cc.fileUtils.setPopupNotify(false);
  
  //ccs.nodeReader = ccs.NodeReader.getInstance();
  ccs.actionTimelineCache = ccs.ActionTimelineCache.getInstance();
  ccs.actionTimelineCache.createAction = ccs.ActionTimelineCache.createAction;
  
  ccs.csLoader = ccs.CSLoader.getInstance();
  ccs.csLoader.createNode = ccs.CSLoader.createNode;
  ccs.csLoader.createTimeline = ccs.CSLoader.createTimeline;
  
  /**
   * @type {Object}
   * @name cc.screen
   * The fullscreen API provides an easy way for web content to be presented using the user's entire screen.
   * It's invalid on safari,QQbrowser and android browser
   */
  cc.screen = {
      init: function() {},
      fullScreen: function() {
          return true;
      },
      requestFullScreen: function(element, onFullScreenChange) {
          onFullScreenChange.call();
      },
      exitFullScreen: function() {
          return false;
      },
      autoFullScreen: function(element, onFullScreenChange) {
          onFullScreenChange.call();
      }
  };
  
  cc.EditBox = ccui.EditBox;
  delete ccui.EditBox;
  
  // GUI
  /**
   * @type {Object}
   * UI Helper
   */
  ccui.helper = ccui.Helper;
  
  // In extension
  /**
   * @type {Object} Base object for ccs.uiReader
   * @name ccs.uiReader
   */
  ccs.uiReader = null;
  cc.defineGetterSetter(ccs, "uiReader", function() {
      return ccs.GUIReader.getInstance();
  });
  ccs.GUIReader.prototype.clear = function() {
      ccs.GUIReader.destroyInstance();
  };
  /**
   * @type {Object} Format and manage armature configuration and armature animation
   * @name ccs.armatureDataManager
   */
  ccs.armatureDataManager = null;
  cc.defineGetterSetter(ccs, "armatureDataManager", function() {
      return ccs.ArmatureDataManager.getInstance();
  });
  ccs.ArmatureDataManager.prototype.clear = function() {
      ccs.ArmatureDataManager.destroyInstance();
  };
  /**
   * @type {Object} Base singleton object for ccs.sceneReader
   * @name ccs.sceneReader
   */
  ccs.sceneReader = null;
  cc.defineGetterSetter(ccs, "sceneReader", function() {
      return ccs.SceneReader.getInstance();
  });
  ccs.SceneReader.prototype.clear = function() {
      ccs.SceneReader.destroyInstance();
  };
  ccs.SceneReader.prototype.version = function() {
      return ccs.SceneReader.sceneReaderVersion();
  };
  /**
   * @type {Object} Base singleton object for ccs.ActionManager
   * @name ccs.actionManager
   */
  ccs.actionManager = ccs.ActionManager.getInstance();
  ccs.ActionManager.prototype.clear = function() {
      this.releaseActions();
  };
  
  //ccs.spriteFrameCacheHelper = ccs.SpriteFrameCacheHelper.getInstance();
  //ccs.dataReaderHelper = ccs.DataReaderHelper.getInstance();
  
  //+++++++++++++++++++++++Define singleton objects end+++++++++++++++++++++++++++
  
  
  //+++++++++++++++++++++++++Redefine JSB only APIs+++++++++++++++++++++++++++
  
  /**
   * @namespace jsb
   * @name jsb
   */
  var jsb = jsb || {};
  /**
   * @type {Object}
   * @name jsb.fileUtils
   * jsb.fileUtils is the native file utils singleton object,
   * please refer to Cocos2d-x API to know how to use it.
   * Only available in JSB
   */
  jsb.fileUtils = cc.fileUtils;
  delete cc.FileUtils;
  delete cc.fileUtils;
  /**
   * @type {Object}
   * @name jsb.AssetsManager
   * jsb.AssetsManager is the native AssetsManager for your game resources or scripts.
   * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/assets-manager/en
   * Only available in JSB
   */
  jsb.AssetsManager = cc.AssetsManager;
  delete cc.AssetsManager;
  /**
   * @type {Object}
   * @name jsb.EventListenerAssetsManager
   * jsb.EventListenerAssetsManager is the native event listener for AssetsManager.
   * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/assets-manager/en
   * Only available in JSB
   */
  jsb.EventListenerAssetsManager = cc.EventListenerAssetsManager;
  delete cc.EventListenerAssetsManager;
  /**
   * @type {Object}
   * @name jsb.EventAssetsManager
   * jsb.EventAssetsManager is the native event for AssetsManager.
   * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/assets-manager/en
   * Only available in JSB
   */
  jsb.EventAssetsManager = cc.EventAssetsManager;
  delete cc.EventAssetsManager;
  
  /**
   * @type {Object}
   * @name jsb.reflection
   * jsb.reflection is a bridge to let you invoke Java static functions.
   * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/reflection/en
   * Only available on Android platform
   */
  jsb.reflection = {
      callStaticMethod : function(){
          cc.log("not supported on current platform");
      }
  };
  
  //+++++++++++++++++++++++++Redefine JSB only APIs+++++++++++++++++++++++++++++
  
  
  //+++++++++++++++++++++++++something about window events begin+++++++++++++++++++++++++++
  cc.winEvents = {//TODO register hidden and show callback for window
      hiddens : [],
      shows : []
  };
  //+++++++++++++++++++++++++something about window events end+++++++++++++++++++++++++++++
  
  //+++++++++++++++++++++++++something about sys begin+++++++++++++++++++++++++++++
  cc._initSys = function(config, CONFIG_KEY){
  
      var locSys = cc.sys = sys || {};
  
      /**
       * English language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_ENGLISH = "en";
      /**
       * Chinese language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_CHINESE = "zh";
      /**
       * French language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_FRENCH = "fr";
      /**
       * Italian language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_ITALIAN = "it";
      /**
       * German language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_GERMAN = "de";
      /**
       * Spanish language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_SPANISH = "es";
      
      /**
       * Netherlands language code
       * @type {string}
       */
      locSys.LANGUAGE_DUTCH = "nl";
      /**
       * Dutch language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_DUTCH = "du";
      /**
       * Russian language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_RUSSIAN = "ru";
      /**
       * Korean language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_KOREAN = "ko";
      /**
       * Japanese language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_JAPANESE = "ja";
      /**
       * Hungarian language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_HUNGARIAN = "hu";
      /**
       * Portuguese language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_PORTUGUESE = "pt";
      /**
       * Arabic language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_ARABIC = "ar";
      /**
       * Norwegian language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_NORWEGIAN = "no";
      /**
       * Polish language code
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LANGUAGE_POLISH = "pl";
  
  
      /**
       * @constant
       * @default
       * @type {string}
       */
      locSys.OS_WINDOWS = "Windows";
      /**
       * @constant
       * @default
       * @type {string}
       */
      locSys.OS_IOS = "iOS";
      /**
       * @constant
       * @default
       * @type {string}
       */
      locSys.OS_OSX = "OS X";
      /**
       * @constant
       * @default
       * @type {string}
       */
      locSys.OS_UNIX = "UNIX";
      /**
       * @constant
       * @default
       * @type {string}
       */
      locSys.OS_LINUX = "Linux";
      /**
       * @constant
       * @default
       * @type {string}
       */
      locSys.OS_ANDROID = "Android";
      locSys.OS_UNKNOWN = "unknown";
  
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.WINDOWS = 0;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.LINUX = 1;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.MACOS = 2;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.ANDROID = 3;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.IPHONE = 4;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.IPAD = 5;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.BLACKBERRY = 6;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.NACL = 7;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.EMSCRIPTEN = 8;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.TIZEN = 9;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.WINRT = 10;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.WP8 = 11;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.MOBILE_BROWSER = 100;
      /**
       * @constant
       * @default
       * @type {Number}
       */
      locSys.DESKTOP_BROWSER = 101;
  
      locSys.BROWSER_TYPE_WECHAT = "wechat";
      locSys.BROWSER_TYPE_ANDROID = "androidbrowser";
      locSys.BROWSER_TYPE_IE = "ie";
      locSys.BROWSER_TYPE_QQ = "qqbrowser";
      locSys.BROWSER_TYPE_MOBILE_QQ = "mqqbrowser";
      locSys.BROWSER_TYPE_UC = "ucbrowser";
      locSys.BROWSER_TYPE_360 = "360browser";
      locSys.BROWSER_TYPE_BAIDU_APP = "baiduboxapp";
      locSys.BROWSER_TYPE_BAIDU = "baidubrowser";
      locSys.BROWSER_TYPE_MAXTHON = "maxthon";
      locSys.BROWSER_TYPE_OPERA = "opera";
      locSys.BROWSER_TYPE_MIUI = "miuibrowser";
      locSys.BROWSER_TYPE_FIREFOX = "firefox";
      locSys.BROWSER_TYPE_SAFARI = "safari";
      locSys.BROWSER_TYPE_CHROME = "chrome";
      locSys.BROWSER_TYPE_UNKNOWN = "unknown";
  
      /**
       * Is native ? This is set to be true in jsb auto.
       * @constant
       * @default
       * @type {Boolean}
       */
      locSys.isNative = true;
  
      /** Get the os of system */
      locSys.os = __getOS();
  
      /** Get the target platform of system */
      locSys.platform = __getPlatform();
  
      // Forces the garbage collector
      locSys.garbageCollect = function() {
          __jsc__.garbageCollect();
      };
  
      // Dumps rooted objects
      locSys.dumpRoot = function() {
          __jsc__.dumpRoot();
      };
  
      // restarts the JS VM
      locSys.restartVM = function() {
          __restartVM();
      };
  
      locSys.dump = function(){
          var self = this;
          var str = "";
          str += "isMobile : " + self.isMobile + "\r\n";
          str += "language : " + self.language + "\r\n";
          str += "browserType : " + self.browserType + "\r\n";
          str += "capabilities : " + JSON.stringify(self.capabilities) + "\r\n";
          str += "os : " + self.os + "\r\n";
          str += "platform : " + self.platform + "\r\n";
          cc.log(str);
      }
  
      locSys.isMobile = (locSys.os == locSys.OS_ANDROID || locSys.os == locSys.OS_IOS) ? true : false;
  
      locSys.language = (function(){
          var language = cc.Application.getInstance().getCurrentLanguage();
          switch(language){
              case 0: return locSys.LANGUAGE_ENGLISH;
              case 1: return locSys.LANGUAGE_CHINESE;
              case 2: return locSys.LANGUAGE_FRENCH;
              case 3: return locSys.LANGUAGE_ITALIAN;
              case 4: return locSys.LANGUAGE_GERMAN;
              case 5: return locSys.LANGUAGE_SPANISH;
              case 6: return locSys.LANGUAGE_DUTCH;
              case 7: return locSys.LANGUAGE_RUSSIAN;
              case 8: return locSys.LANGUAGE_KOREAN;
              case 9: return locSys.LANGUAGE_JAPANESE;
              case 10: return locSys.LANGUAGE_HUNGARIAN;
              case 11: return locSys.LANGUAGE_PORTUGUESE;
              case 12: return locSys.LANGUAGE_ARABIC;
              case 13: return locSys.LANGUAGE_NORWEGIAN;
              case 14: return locSys.LANGUAGE_POLISH;
              default : return locSys.LANGUAGE_ENGLISH;
          }
      })();
  
      /** The type of browser */
      locSys.browserType = null;//null in jsb
  
      var capabilities = locSys.capabilities = {"opengl":true};
      if( locSys.isMobile ) {
          capabilities["accelerometer"] = true;
          capabilities["touches"] = true;
      } else {
          // desktop
          capabilities["keyboard"] = true;
          capabilities["mouse"] = true;
      }
  };
  
  //+++++++++++++++++++++++++something about sys end+++++++++++++++++++++++++++++
  //+++++++++++++++++++++++++something about log start++++++++++++++++++++++++++++
  /**
   * Init Debug setting.
   * @function
   */
  cc._initDebugSetting = function (mode) {
      var ccGame = cc.game;
      var bakLog = cc._cocosplayerLog || cc.log || log;
      cc.log = cc.warn = cc.error = cc.assert = function(){};
      if(mode == ccGame.DEBUG_MODE_NONE){
      }else{
          cc.error = function(){
              bakLog.call(this, "ERROR :  " + cc.formatStr.apply(cc, arguments));
          };
          cc.assert = function(cond, msg) {
              if (!cond && msg) {
                  var args = [];
                  for (var i = 1; i < arguments.length; i++)
                      args.push(arguments[i]);
                  bakLog("Assert: " + cc.formatStr.apply(cc, args));
              }
          };
          if(mode != ccGame.DEBUG_MODE_ERROR && mode != ccGame.DEBUG_MODE_ERROR_FOR_WEB_PAGE){
              cc.warn = function(){
                  bakLog.call(this, "WARN :  " + cc.formatStr.apply(cc, arguments));
              };
          }
          if(mode == ccGame.DEBUG_MODE_INFO || mode == ccGame.DEBUG_MODE_INFO_FOR_WEB_PAGE){
              cc.log = function(){
                  bakLog.call(this, cc.formatStr.apply(cc, arguments));
              };
          }
      }
  };
  //+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
  
  
  //+++++++++++++++++++++++++something about CCGame begin+++++++++++++++++++++++++++
  
  /**
   * @type {Object}
   * @name cc.game
   * An object to boot the game.
   */
  cc.game = {
      DEBUG_MODE_NONE : 0,
      DEBUG_MODE_INFO : 1,
      DEBUG_MODE_WARN : 2,
      DEBUG_MODE_ERROR : 3,
      DEBUG_MODE_INFO_FOR_WEB_PAGE : 4,
      DEBUG_MODE_WARN_FOR_WEB_PAGE : 5,
      DEBUG_MODE_ERROR_FOR_WEB_PAGE : 6,
  
      EVENT_HIDE: "game_on_hide",
      EVENT_SHOW: "game_on_show",
      
      /**
       * Key of config
       * @constant
       * @default
       * @type {Object}
       */
      CONFIG_KEY : {
          engineDir : "engineDir",
          dependencies : "dependencies",
          debugMode : "debugMode",
          showFPS : "showFPS",
          frameRate : "frameRate",
          id : "id",
          renderMode : "renderMode",
          jsList : "jsList",
          classReleaseMode : "classReleaseMode"
      },
      
      _prepareCalled : false,//whether the prepare function has been called
      _prepared : false,//whether the engine has prepared
      _paused : true,//whether the game is paused
      
      _intervalId : null,//interval target of main
      
      
      /**
       * Config of game
       * @type {Object}
       */
      config : null,
      
      /**
       * Callback when the scripts of engine have been load.
       * @type {Function}
       */
      onStart : null,
      
      /**
       * Callback when game exits.
       * @type {Function}
       */
      onExit : null,
      /**
       * Callback before game resumes.
       * @type {Function}
       */
      onBeforeResume : null,
      /**
       * Callback after game resumes.
       * @type {Function}
       */
      onAfterResume : null,
      /**
       * Callback before game pauses.
       * @type {Function}
       */
      onBeforePause : null,
      /**
       * Callback after game pauses.
       * @type {Function}
       */
      onAfterPause : null,
      
      /**
       * Set frameRate of game.
       * @param frameRate
       */
      setFrameRate : function(frameRate){
          var self = this, config = self.config, CONFIG_KEY = self.CONFIG_KEY;
          config[CONFIG_KEY.frameRate] = frameRate;
          cc.director.setAnimationInterval(1.0/frameRate);
      },
      /**
       * Run game.
       */
      run : function(){
          var self = this;
          if(!self._prepareCalled){
              self.prepare(function(){
                  self.onStart();
              });
          }else{
              self.onStart();
          }
      },
      /**
       * Init config.
       * @param cb
       * @returns {*}
       * @private
       */
      _initConfig : function(){
          cc._initDebugSetting(1);
          var self = this, CONFIG_KEY = self.CONFIG_KEY;
          var _init = function(cfg){
              cfg[CONFIG_KEY.engineDir] = cfg[CONFIG_KEY.engineDir] || "frameworks/cocos2d-html5";
              cfg[CONFIG_KEY.debugMode] = cfg[CONFIG_KEY.debugMode] || 0;
              cfg[CONFIG_KEY.frameRate] = cfg[CONFIG_KEY.frameRate] || 60;
              cfg[CONFIG_KEY.renderMode] = cfg[CONFIG_KEY.renderMode] || 0;
              cfg[CONFIG_KEY.showFPS] = cfg[CONFIG_KEY.showFPS] === false ? false : true;
              return cfg;
          };
          try{
              var txt = jsb.fileUtils.getStringFromFile("project.json");
              var data = JSON.parse(txt);
              this.config = _init(data || {});
          }catch(e){
              cc.log("Failed to read or parse project.json");
              this.config = _init({});
          }
          cc._initDebugSetting(this.config[CONFIG_KEY.debugMode]);
          cc.director.setDisplayStats(this.config[CONFIG_KEY.showFPS]);
          cc.director.setAnimationInterval(1.0/this.config[CONFIG_KEY.frameRate]);
          cc._initSys(this.config, CONFIG_KEY);
      },
      
      //cache for js and module that has added into jsList to be loaded.
      _jsAddedCache : {},
      _getJsListOfModule : function(moduleMap, moduleName, dir){
          var jsAddedCache = this._jsAddedCache;
          if(jsAddedCache[moduleName]) return null;
          dir = dir || "";
          var jsList = [];
          var tempList = moduleMap[moduleName];
          if(!tempList) throw "can not find module [" + moduleName + "]";
          var ccPath = cc.path;
          for(var i = 0, li = tempList.length; i < li; i++){
              var item = tempList[i];
              if(jsAddedCache[item]) continue;
              var extname = ccPath.extname(item);
              if(!extname) {
                  var arr = this._getJsListOfModule(moduleMap, item, dir);
                  if(arr) jsList = jsList.concat(arr);
              }else if(extname.toLowerCase() == ".js") jsList.push(ccPath.join(dir, item));
              jsAddedCache[item] = true;
          }
          return jsList;
      },
      /**
       * Prepare game.
       * @param cb
       */
      prepare : function(cb){
          var self = this, config = self.config, CONFIG_KEY = self.CONFIG_KEY, loader = cc.loader;
          require("script/jsb.js");
          self._prepareCalled = true;
          loader.loadJsWithImg("", config[CONFIG_KEY.jsList] || [], function(err){
              if(err) throw err;
              self._prepared = true;
              if(cb) cb();
          });
      }
  };
  cc.game._initConfig();
  
  //+++++++++++++++++++++++++something about CCGame end+++++++++++++++++++++++++++++
  
  //+++++++++++++++++++++++++other initializations+++++++++++++++++++++++++++++
  
  // JS to Native bridges
  if(window.JavascriptJavaBridge && cc.sys.os == cc.sys.OS_ANDROID){
      jsb.reflection = new JavascriptJavaBridge();
      cc.sys.capabilities["keyboard"] = true;
  }
  else if(window.JavaScriptObjCBridge && (cc.sys.os == cc.sys.OS_IOS || cc.sys.os == cc.sys.OS_OSX)){
      jsb.reflection = new JavaScriptObjCBridge();
  }
  
  jsb.urlRegExp = new RegExp(
      "^" +
          // protocol identifier
          "(?:(?:https?|ftp)://)" +
          // user:pass authentication
          "(?:\\S+(?::\\S*)?@)?" +
          "(?:" +
              // IP address exclusion
              // private & local networks
              "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
              "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
              "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
              // IP address dotted notation octets
              // excludes loopback network 0.0.0.0
              // excludes reserved space >= 224.0.0.0
              // excludes network & broacast addresses
              // (first & last IP address of each class)
              "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
              "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
              "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
          "|" +
              // host name
              "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
              // domain name
              "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
              // TLD identifier
              "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
          ")" +
          // port number
          "(?::\\d{2,5})?" +
          // resource path
          "(?:/\\S*)?" +
      "$", "i"
  );
  
  //+++++++++++++++++++++++++other initializations end+++++++++++++++++++++++++++++
  