/*
资源，支持远程路径与本地路径
@param   {String}    绝对路径
@param   {String}    内容。可选，如果为 String 则直接返回 Promise 对象
@param   {Object}    选项。@see Resource.defaults
@return  {Promise}
438987
function Resource (file, content, options) {

    options = utils.options(Resource.defaults, options);
    
    var resource;
    var data = new Resource.Model(file, content, options);

    var cache = options.cache;
    var resourceBeforeLoad = options.resourceBeforeLoad;
    var resourceLoad = options.resourceLoad;
    var resourceError = options.resourceError;
    
    resourceBeforeLoad(file);

    if (cache) {
        resource = Resource.cache[file];
        if (resource) {
            return resource.then(function (data) {

                // 深拷贝缓存
                data = new Resource.Model(
                    data.file,
                    data.content,
                    utils.copy(data.options)
                );

                resourceLoad(file, data);
                
                return data;
            }, function (errors) {
                resourceError(file, errors);
                return Promise.reject(errors);
            });
        }
    }


    if (typeof content === 'string') {
        return Promise.resolve(data);
    }


    resource = new Promise(function (resolve, reject) {

        // 远程文件
        if (utils.isRemoteFile(file)) {

            
            var location = url.parse(file);
            var protocol = location.protocol === 'http:' ? http : https;

            var request = protocol.request({
                method: 'GET',
                host: location.host,
                hostname: location.hostname,
                path: location.path,
                port: location.port,
                headers: {
                    'accept-encoding': 'gzip,deflate'
                }
            }, function (res) {

                var encoding = res.headers['content-encoding'];
                var type = res.headers['content-type'];
                var errors = null;


                if (res.statusCode !== 200) {
                    errors = new Error(res.statusMessage);
                } else if (type.indexOf('text/') !== 0) {
                    errors = new Error('only supports `text/*` resources');
                }


                if (errors) {
                    reject(errors);
                } else {

                    var buffer = new Buffer([]);


                    if (encoding === 'undefined') {
                        res.setEncoding('utf-8'); 
                    }


                    res.on('data', function (chunk) {
                        buffer = Buffer.concat([buffer, chunk]);
                    });

                    res.on('end', function () {                

                        if (encoding === 'gzip') {

                            zlib.unzip(buffer, function(errors, buffer) {
                                if (errors) {
                                    reject(errors);
                                } else {
                                    resolve(buffer.toString());
                                }
                            });

                        } else if (encoding == 'deflate') {

                            zlib.inflate(buffer, function (errors, decoded) {
                                if (errors) {
                                    reject(errors);
                                } else {
                                    resolve(decoded.toString());
                                }
                            });

                        } else {
                            resolve(buffer.toString());
                        }

                    });

                }

            })
            .on('error', reject);

            request.end();


        // 本地文件
        } else {

            
            fs.readFile(file, 'utf8', function (errors, content) {

                if (errors) {
                    reject(errors);
                } else {
                    resolve(content);
                }

            });

        }
    })
    .then(function (content) {
        data.content = content;
        resourceLoad(file, data);
        return data;
    })
    .catch(function (errors) {
        errors = new VError(errors, 'ENOENT, load "%s" failed', file);
        resourceError(file, errors);
        return Promise.reject(errors);
    });

    if (cache) {
        Resource.cache[file] = resource;
    }

    return resource;
}
398672
function sendRequest(url) {
        return new Promise((resolve, reject) => {
            request(url, (error, response, body) => {
                    if (!error && response.statusCode == 200) {
                        if (body.errcode) {
                            console.warn(body.errmsg);
                            reject(body.errmsg);
                        }
                        else {
                            resolve(body);
                        }
                    }
                    else {
                        console.warn(error);
                        reject(error);
                    }
                }
            );
        });
    }
785099
function (providerConstr, args) {
    return new Promise(function (resolve) {
        var instance = new providerConstr();
        addInstanceToStore(args, instance);
        createGetData(instance, args.caller);
        if (args.hasOwnProperty("handler")) {
            instance.setHandler(args.handler);
        }
        if (args.hasOwnProperty("resources")) {
            instance.setResources(args.resources);
        }
        instance.fetchData(resolve, args.caller);
    });
}
1113090
function AjaxPreloadPromise(pageDOM) {
  const self = this;
  return new Promise((resolve, reject) => {
    let asyncTasks = [];
    console.time("预加载Ajax用时");

    /***
     * 查看是否有需要预加载的Ajax页面
     */
    $(pageDOM).find("a[ct-data-preload=true][ct-pageId]").each((index, aDom) => {
      const ctDataAjax = aDom.getAttribute("ct-data-ajax");
      const pageId = aDom.getAttribute("ct-pageId");

      if (
        !pageId &&
        ctDataAjax &&
        ctDataAjax === "false"
      ) {
        return false;
      }

      const pageRouterConfig = self.config.router[pageId];
      const href = (pageRouterConfig && pageRouterConfig.url) ? pageRouterConfig.url : "";
      if (!href) {
        return false;
      }

      asyncTasks.push($.ajax({
        dataType: "text",
        url: href,
        success: (templateText) => {
          this.templateDB[pageId] = CtMobileFactory.getPageTemplateStrByAjaxStr(templateText);
        },
        error: (error, status, thrown) => {
          reject(error);
        }
      }));
    });

    if (asyncTasks.length !== 0) {
      Promise.all(asyncTasks).then(() => {
        console.timeEnd("预加载Ajax用时");
        resolve();
      }).catch(() => {
        reject();
      });
    } else {
      resolve();
    }
  });
}
550458
function getFile(fn) {
	return new Promise((a, b) => _fs2.default.readFile(fn, 'utf-8', (e, d) => e ? b(e) : a(d)));
}
182413
async function repeatablePromise (initialAssumptions, assumptionsFromResult, promiseGenerator) {
    let promise = promiseGenerator(initialAssumptions);
    let result = await promise;
    let finalAssumptions = assumptionsFromResult(result);
    if (JSON.stringify(initialAssumptions) === JSON.stringify(finalAssumptions)) {
        return promise;
    } else {
        return promiseGenerator(finalAssumptions);
    }
}
510203
function nodeGet(url) {
  // return new pending promise
  return new Promise(function (resolve, reject) {
    // select http or https module, depending on reqested url
    var lib = url.startsWith("https") ? require("https") : require("http");
    var request = lib.get(url, function (response) {
      // handle http errors
      if (response.statusCode < 200 || response.statusCode > 299) {
        reject(new Error("Failed to load page, status code: " + response.statusCode));
      }
      // temporary data holder
      var body = [];
      // on every content chunk, push it to the data array
      response.on("data", function (chunk) {
        return body.push(chunk);
      });
      // we are done, resolve promise with those joined chunks
      response.on("end", function () {
        return resolve(body.join(""));
      });
    });
    // handle connection errors of the request
    request.on("error", function (err) {
      return reject(err);
    });
  });
}
1212669
function makeRequest(url) {
    return new Promise(function (resolve, reject) {
      request.get(url).responseType('json').type('application/json').accept('application/json').end(function (err, res) {
        if (err) {
          reject(err);
        } else {
          resolve(res.body);
        }
      });
    });
  }
1034893
async function replace(string, regex, callback) {
	regex.lastIndex = 0;

	/* get all data */
	const promises = [];
	string.replace(regex, (match, ...args) => {
		const promise = callback(match, ...args);
		promises.push(promise);
	});
	const data = await Promise.all(promises);

	/* replace all data */
	return data.length ? string.replace(regex, () => data.shift()) : string;
}
1076968
function(file) {
        var self = this;

        return new Promise(function(resolve) {
            fs.readFileAsync(file, 'utf-8')
                .then(function(content) {
                    return self._parseFile(file, content);
                })
                .then(function(ast) {
                    return self._getConfig(file, ast);
                })
                .then(function(config) {
                    self._modules = self._modules.concat(config);

                    resolve(config);
                });
        });
    }
1002908
function httpToFloraRequest(httpRequest) {
    return new Promise((resolve, reject) => {
        const parsedUrl = url.parse(httpRequest.url, true);
        const matches = parsedUrl.pathname.match(/^\/(.+)\/([^/.]*)(?:\.([a-z]+))?$/);
        if (!matches) {
            resolve(null);
            return;
        }

        /*
         * Gather GET parameters.
         */
        const opts = {
            resource: matches[1],
            _status: httpRequest.flora.status,
            _httpRequest: httpRequest
        };

        if (matches[2]) opts.id = matches[2];
        if (matches[3]) opts.format = matches[3];

        Object.keys(parsedUrl.query).forEach(key => {
            if (!Object.prototype.hasOwnProperty.call(opts, key)) {
                if (Array.isArray(parsedUrl.query[key])) {
                    reject(new RequestError(`Duplicate parameter "${key}" in URL`));
                    return;
                }

                opts[key] = parsedUrl.query[key];
            }
        });

        /*
         * Handle POST payload.
         */
        httpRequest.on('error', err => reject(new RequestError('Error reading HTTP-Request: ' + err.message)));

        if (httpRequest.method === 'POST' && !Number.isNaN(Number(httpRequest.headers['content-length']))) {
            let payload = '';
            let contentTypes;

            if (httpRequest.headers['content-type']) {
                contentTypes = contentType.parse(httpRequest.headers['content-type']);
            } else {
                reject(new RequestError('Missing required Content-Type headers'));
                return;
            }

            if (contentTypes.type === 'application/json' || contentTypes.type === 'application/x-www-form-urlencoded') {
                // POST Form Data or JSON
                httpRequest.setEncoding(contentTypes.parameters.charset || 'utf-8');
                httpRequest.on('data', chunk => {
                    payload += chunk;
                });

                httpRequest.on('end', () => {
                    if (contentTypes.type === 'application/x-www-form-urlencoded') {
                        payload = querystring.parse(payload);
                        Object.keys(payload).forEach(key => {
                            if (!Object.prototype.hasOwnProperty.call(opts, key)) {
                                if (Array.isArray(payload[key])) {
                                    reject(new RequestError(`Duplicate parameter "${key}" in Payload`));
                                    return;
                                }

                                opts[key] = payload[key];
                            }
                        });
                    } else if (contentTypes.type === 'application/json') {
                        try {
                            opts.data = JSON.parse(payload);
                        } catch (err) {
                            reject(new RequestError('Invalid payload, must be valid JSON'));
                            return;
                        }
                    }

                    resolve(new Request(opts));
                });
            } else {
                // multipart file upload or other content types (e.g. single file upload)
                const busboy = new Busboy({ headers: httpRequest.headers });
                busboy.on('error', err => reject(err));
                opts.data = busboy;
                resolve(new Request(opts));
                setImmediate(() => httpRequest.pipe(busboy));
            }
        } else {
            resolve(new Request(opts));
        }
    });
}
675515
function contentsAsync(file, options, cb) {
  if (typeof options === 'function') {
    cb = options;
    options = {};
  }

  if (typeof cb !== 'function') {
    throw new TypeError('expected a callback function');
  }

  if (!utils.isObject(file)) {
    cb(new TypeError('expected file to be an object'));
    return;
  }

  contentsSync(file, options);
  cb(null, file);
}
1285370
function requireJSAsync (file) {
	return new Promise(function (resolve, reject) {
		requireJS([ 'rvc!' + requireJSPath(file, '.html') ], resolve, reject);
	});
}
1198280
function requestHandler(req, res, next) {
  const start = Date.now();
  let source;

  return Promise.try(() => {
    source = core.getPublicSource(req.params.src);
    return source.getHandler().getInfoAsync().then(info => [info, infoHeaders]);
  }).spread((data, dataHeaders) => {
    core.setResponseHeaders(res, source, dataHeaders);

    if (req.query && req.query.format) {
      const escapedText = JSON.stringify(data, null, ' ').replace(/&/g, '&amp;').replace(/</g, '&lt;');
      res.send(`<pre>${escapedText}</pre>`);
    } else {
      res.json(data);
    }

    const mx = util.format('req.%s.info', req.params.src);
    core.metrics.endTiming(mx, start);
  }).catch(err => core.reportRequestError(err, res)).catch(next);
}
1120975
function fetchText(address, contentType) {
    return get(address, contentType)
        .then(streamToText)
        .catch(err => {
            console.error(`Fetch error: ${err.message}`);
            throw err; // re-throw
        });
}
478144
function (token, path, payload, contentFormat) {
            return new Promise((resolve,reject)=>{

                let zh = NewZestHeader();
                zh.code = 2;
                zh.token = token;
                zh.tkl = token.length;
                zh.payload = payload;
                zh.oc = 3;
                zh.options.push(NewZestOptionHeader(11,path,path.length));
                let hostname = os.hostname();
                zh.options.push(NewZestOptionHeader(3,hostname,hostname.length));
                zh.options.push(NewZestOptionHeader(12,contentFormatToInt(contentFormat),2)); //uint32

                let msg = MarshalZestHeader(zh)
                sendRequestAndAwaitResponse(this.ZMQsoc,msg)
                .then((resp)=>{
                    handleResponse(resp,(zh)=>{resolve(zh.payload)},reject);
                })
                .catch((err)=>{
                    reject(err);
                });
            });
        }
824457
function createDocumentLoader(promise) {
    return function(url, callback) {
      promise(url).then(
        // success
        function(remoteDocument) {
          callback(null, remoteDocument);
        },
        // failure
        callback
      );
    };
  }