Waits for the project to finish compiling. Then calls the callback
@param {Project} project
@return {Promise<void>}
551225
function waitForCompletion(project) {
	return new Promise((resolve, reject) => {
		let warned = false;
		project.refreshUntilCompleted((completed, error) => {
			if (!error) {
				if (completed) {
					if (warned) {
						readLine.clearLine(process.stdout);  // clear "Waiting" line
						readLine.cursorTo(process.stdout, 0);  // move cursor to beginning of line
					}
					resolve();
				} else {
					if (!warned) {
						process.stdout.write("Waiting for " + project.name + " compilation to end ");
						warned = true;
					}
					process.stdout.write(".");
				}
			} else {
				reject(error);
			}
		});
	});
}
158794
function waitUntil(fun) {
    var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 20;

    var timedOut = false;
    var ok = false;

    if (timeout !== 0) (0, _wait2['default'])(timeout).then(function () {
        return timedOut = true;
    });

    return new Promise(function (resolve, reject) {
        var runLoop = function runLoop() {
            if (ok) {
                resolve();
                return;
            }
            if (timedOut) {
                reject(new Error('AsyncTestUtil.waitUntil(): reached timeout of ' + timeout + 'ms'));
                return;
            }
            (0, _wait2['default'])(interval).then(function () {
                var value = (0, _promisify2['default'])(fun());
                value.then(function (val) {
                    ok = val;
                    runLoop();
                });
            });
        };
        runLoop();
    });
}
324749
function RedisProject(projectId, adapter) {
    var logger = adapter.logger.fork(projectId);
    this.projectId = projectId;

    this.closeProject = function (callback) {
        var deferred = Q.defer();
        deferred.resolve();
        return deferred.promise.nodeify(callback);
    };

    this.loadObject = function (hash, callback) {
        var deferred = Q.defer();
        if (typeof hash !== 'string') {
            deferred.reject(new Error('loadObject - given hash is not a string : ' + typeof hash));
        } else if (!REGEXP.HASH.test(hash)) {
            deferred.reject(new Error('loadObject - invalid hash :' + hash));
        } else {
            Q.ninvoke(adapter.client, 'hget', projectId, hash)
                .then(function (result) {
                    // Bulk string reply: the value associated with field,
                    // or nil when field is not present in the hash or key does not exist.
                    if (result) {
                        deferred.resolve(JSON.parse(result));
                    } else {
                        logger.error('object does not exist ' + hash);
                        deferred.reject(new Error('object does not exist ' + hash));
                    }
                })
                .catch(deferred.reject);
        }

        return deferred.promise.nodeify(callback);
    };

    this.insertObject = function (object, callback) {
        var deferred = Q.defer();
        if (object === null || typeof object !== 'object') {
            deferred.reject(new Error('object is not an object'));
        } else if (typeof object._id !== 'string' || !REGEXP.HASH.test(object._id)) {
            deferred.reject(new Error('object._id is not a valid hash.'));
        } else {
            Q.ninvoke(adapter.client, 'hsetnx', projectId, object._id, JSON.stringify(object))
                .then(function (result) {
                    // 1 if field is a new field in the hash and value was set.
                    // 0 if field already exists in the hash and no operation was performed.
                    if (result === 0) {
                        Q.ninvoke(adapter.client, 'hget', projectId, object._id)
                            .then(function (objectStr) {
                                var errMsg;
                                if (CANON.stringify(object) === CANON.stringify(JSON.parse(objectStr))) {
                                    logger.info('tried to insert existing hash - the two objects were equal',
                                        object._id);
                                    deferred.resolve();
                                } else {
                                    errMsg = 'tried to insert existing hash - the two objects were NOT equal ';
                                    logger.error(errMsg, {
                                        metadata: {
                                            newObject: CANON.stringify(object),
                                            oldObject: CANON.stringify(JSON.parse(objectStr))
                                        }
                                    });
                                    deferred.reject(new Error(errMsg + object._id));
                                }
                            })
                            .catch(deferred.reject);
                    } else {
                        if (object.type === CONSTANTS.COMMIT_TYPE) {
                            Q.ninvoke(adapter.client, 'hset', projectId + adapter.CONSTANTS.COMMITS,
                                object._id, object.time)
                                .then(function () {
                                    deferred.resolve();
                                })
                                .catch(deferred.reject);
                        } else {
                            deferred.resolve();
                        }
                    }
                });
        }

        return deferred.promise.nodeify(callback);
    };

    this.getBranches = function (callback) {
        return Q.ninvoke(adapter.client, 'hgetall', projectId + adapter.CONSTANTS.BRANCHES)
            .then(function (result) {
                return result || {};
            })
            .nodeify(callback);
    };

    this.getBranchHash = function (branch, callback) {
        return Q.ninvoke(adapter.client, 'hget', projectId + adapter.CONSTANTS.BRANCHES, branch)
            .then(function (branchHash) {
                return branchHash || '';
            }).nodeify(callback);
    };

    this.setBranchHash = function (branch, oldhash, newhash, callback) {
        var deferred = Q.defer(),
            branchesHashMap = projectId + adapter.CONSTANTS.BRANCHES;

        if (oldhash === newhash) {
            Q.ninvoke(adapter.client, 'hget', branchesHashMap, branch)
                .then(function (branchHash) {
                    branchHash = branchHash || '';
                    if (branchHash === oldhash) {
                        deferred.resolve();
                    } else {
                        deferred.reject(new Error('branch hash mismatch'));
                    }
                })
                .catch(deferred.reject);
        } else if (newhash === '') {
            Q.ninvoke(adapter.client, 'hget', branchesHashMap, branch)
                .then(function (branchHash) {
                    if (branchHash === oldhash) {
                        Q.ninvoke(adapter.client, 'hdel', branchesHashMap, branch)
                            .then(deferred.resolve);
                    } else if (branchHash === null) {
                        deferred.resolve();
                    } else {
                        deferred.reject(new Error('branch hash mismatch'));
                    }
                })
                .catch(deferred.reject);
        } else if (oldhash === '') {
            Q.ninvoke(adapter.client, 'hsetnx', branchesHashMap, branch, newhash)
                .then(function (result) {
                    // 1 if field is a new field in the hash and value was set.
                    // 0 if field already exists in the hash and no operation was performed.
                    if (result === 1) {
                        deferred.resolve();
                    } else {
                        deferred.reject(new Error('branch hash mismatch'));
                    }
                })
                .catch(deferred.reject);
        } else {
            Q.ninvoke(adapter.client, 'hget', branchesHashMap, branch)
                .then(function (branchHash) {
                    if (branchHash === oldhash) {
                        Q.ninvoke(adapter.client, 'hset', branchesHashMap, branch, newhash)
                            .then(function () {
                                deferred.resolve();
                            })
                            .catch(deferred.reject);
                    } else {
                        deferred.reject(new Error('branch hash mismatch'));
                    }
                })
                .catch(deferred.reject);
        }

        return deferred.promise.nodeify(callback);
    };

    this.getCommits = function (before, number, callback) {
        return Q.ninvoke(adapter.client, 'hgetall', projectId + adapter.CONSTANTS.COMMITS)
            .then(function (result) {
                var i,
                    hashArray,
                    timestamp,
                    hashKeys = Object.keys(result || {}),
                    commitsInfo = [];

                // FIXME: This is not a very optimized implementation
                for (i = 0; i < hashKeys.length; i += 1) {
                    timestamp = parseInt(result[hashKeys[i]], 10);
                    if (timestamp < before) {
                        commitsInfo.push({
                            hash: hashKeys[i],
                            time: timestamp
                        });
                    }
                }

                commitsInfo.sort(function (a, b) {
                    return b.time - a.time;
                });

                hashArray = commitsInfo.slice(0, number).map(function (commitInfo) {
                    return commitInfo.hash;
                });

                if (hashArray.length > 0) {
                    hashArray.unshift(projectId);
                    return Q.ninvoke(adapter.client, 'hmget', hashArray);
                } else {
                    return [];
                }
            })
            .then(function (commitObjects) {
                return commitObjects.map(function (commitObject) {
                    return JSON.parse(commitObject);
                });
            })
            .nodeify(callback);
    };

    this.createTag = function (name, commitHash, callback) {
        var deferred = Q.defer();

        Q.ninvoke(adapter.client, 'hsetnx', projectId + adapter.CONSTANTS.TAGS, name, commitHash)
            .then(function (result) {
                // 1 if field is a new field in the hash and value was set.
                // 0 if field already exists in the hash and no operation was performed.
                if (result === 1) {
                    deferred.resolve();
                } else {
                    deferred.reject(new Error('Tag already exists [' + name + ']'));
                }
            })
            .catch(deferred.reject);

        return deferred.promise.nodeify(callback);
    };

    this.deleteTag = function (name, callback) {
        return Q.ninvoke(adapter.client, 'hdel', projectId + adapter.CONSTANTS.TAGS, name)
            .nodeify(callback);
    };

    this.getTags = function (callback) {
        return Q.ninvoke(adapter.client, 'hgetall', projectId + adapter.CONSTANTS.TAGS)
            .then(function (result) {
                return result || {};
            })
            .nodeify(callback);
    };
}
45169
function createSingleCompiler(webpackConfig: WebpackCompiler): Promise<any> {
  return new Promise((resolve, reject) => {
    try {
      webpack(webpackConfig, (err, stats) => {
        if (err || stats.hasErrors()) {
          debug(err);
          return reject(err);
        }

        return resolve();
      });
    } catch (e) {
      return reject(e);
    }
  });
}
721957
function async(makeGenerator, callback) {
  return function() {
    const generator = makeGenerator.apply(this, arguments);
    const handle = getHandle(generator, callback);
    try {
      return handle(generator.next());
    } catch(err) {
      return Promise.reject(err);
    }
  };
}
450812
function utilCallbackAfterPromise(self, func, args, cb) {
	args = Array.prototype.slice.apply(args);
	let lastarg = args.pop();
	if(!cb) cb = lastarg;
	func.apply(self, args).then(res => {
		try {
			cb(null, res);
		} catch(e) {
			process.nextTick(() => { throw e });
		}
	}).catch((err) => {
		try {
			cb(err);
		} catch(e) {
			process.nextTick(() => { throw e });
		}
	});
}
1153874
function (resolvedCallback, errorCallback, progressCallback) {
        var returnDeferred = new Deferred(this._canceller), //new Deferred(this.getPromise().cancel)
            listener = {
                resolved : resolvedCallback,
                error : errorCallback,
                progress : progressCallback,
                deferred : returnDeferred
            };

        if (this.finished) {
            this._notify(listener);
        } else {
            this.waiting.push(listener);
        }
        return returnDeferred.getPromise();
    }
588661
function waitForever(fun) {
  var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  var interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 20;

  return new Promise(function (res) {});
}
1312305
function Promise () {
	this.deferred = false;
	this.handlers = [];
	this.state    = promise.state.PENDING;
	this.value    = null;
}
1113632
function(project) {
        if(project.slug.toLowerCase() === 'obs'
            || project.slug.toLowerCase() === 'bible-obs'
            || project.slug.toLowerCase() === 'bible'
            || !project.chunks_url) return Promise.resolve();


        return request.read(project.chunks_url)
            .then(function(response) {
                // consume chunk data
                if(response.status !== 200) return Promise.reject(response);

                let data;
                try {
                    data = JSON.parse(response.data);
                } catch(err) {
                    console.log(project);
                    return Promise.reject(err);
                }

                try {
                    let language_id = library.addSourceLanguage({
                        slug: 'en',
                        name: 'English',
                        direction: 'ltr'
                    });

                    // TODO: retrieve the correct versification name(s) from the source language
                    let versification_id = library.addVersification({
                        slug: 'en-US',
                        name: 'American English'
                    }, language_id);


                    if (versification_id > 0) {
                        for (let chunk of data) {
                            library.addChunkMarker({
                                chapter: padSlug(chunk.chp, 2),
                                verse: padSlug(chunk.firstvs, 2)
                            }, project.slug, versification_id);
                        }
                    }
                } catch (err) {
                    return Promise.reject(err);
                }
            });
    }
284251
function(params, done) {
      var messageId = generateMessageId();

      assert(params.loaderContext && typeof params.loaderContext === 'object');
      assert(!!fd, "You must launch a compilation thread before attempting to use it!!!");

      callbacks[messageId] = done;

      if (config.debug) {
        console.log('HappyThread[%s]: compiling "%s"... (request=%s)', id, params.loaderContext.resourcePath, messageId);
      }

      send({
        id: messageId,
        name: 'COMPILE',
        data: params,
      });
    }
1305475
function build(projectInfo, backendProject, callback){
    if(isNewBuildNeeded(projectInfo)){
        console.log('   generating backend project content')
        backendContentManager.generateContents(projectInfo, backendProject, function(){
            console.log('   done')
            if(callback){
                callback(true)
            }
        })
    }else{
        if(callback){
            callback(false)
        }
    }
}
888488
function spawn() {
    startInterval();
    var args = Array.prototype.slice.call(arguments);
    if (currentCount < limitCount) {
        currentCount++;
        if (monitorCallback) {
            monitorCallback("start", remainedTasks);
        }
        return new Promise(function (resolved) {
            var process = originalSpawn.apply(null, args);
            process.on("close", function (code) {
                if (monitorCallback) {
                    monitorCallback("close", remainedTasks, code);
                }
                currentCount--;
                if (currentCount === 0 && remainedTasks.length === 0) {
                    callWaitAllCallbacks();
                }
            });
            resolved(process);
        });
    } else {
        var id = taskId++;
        remainedTasks.push([args, id]);
        if (monitorCallback) {
            monitorCallback("added", remainedTasks);
        }
        return new Promise(function (resolved) {
            remainedTaskCallbacks[id] = resolved;
        });
    }
}
86750
function (project_data, cb) {

            _util.buildQuery('projects', project_data, function (error, data) {

                return cb(error, data);

            });

        }
901608
function transpile() {
  return new Promise((resolve, reject) => {
    const result = spawn.sync(
      skyPagesConfigUtil.spaPath('node_modules', '.bin', 'ngc'),
      [
        '--project',
        skyPagesConfigUtil.spaPathTemp('tsconfig.json')
      ],
      { stdio: 'inherit' }
    );

    // Catch ngc errors.
    if (result.err) {
      reject(result.err);
      return;
    }

    // Catch non-zero status codes.
    if (result.status !== 0) {
      reject(new Error(`Angular compiler (ngc) exited with status code ${result.status}.`));
      return;
    }

    resolve();
  });
}
755522
function(callback) {
		this.promises.push(function async(done, utils) {
			callback(utils.lastReturn, done, utils);
		});
		return this;
	}
472760
function (promise){
    		promise.success = function (fn) {
	            promise.then(fn);
	            return promise;
	        };

	        promise.error = function (fn) {
	            promise.then(null, fn);
	            return promise;
	        };
    	}