text:
/*
 * Throughout this file, the term "outer scope" is used to refer to the outer-
 * most/global/root Scope objects for particular file. The term "inner scope"
 * is used to refer to a Scope object that is reachable via the child relation
 * from an outer scope.
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, Worker, setTimeout */

define(function (require, exports, module) {
    "use strict";

    var _ = brackets.getModule("thirdparty/lodash");

    var CodeMirror          = brackets.getModule("thirdparty/CodeMirror/lib/codemirror"),
        DefaultDialogs      = brackets.getModule("widgets/DefaultDialogs"),
        Dialogs             = brackets.getModule("widgets/Dialogs"),
        DocumentManager     = brackets.getModule("document/DocumentManager"),
        EditorManager       = brackets.getModule("editor/EditorManager"),
        ExtensionUtils      = brackets.getModule("utils/ExtensionUtils"),
        FileSystem          = brackets.getModule("filesystem/FileSystem"),
        FileUtils           = brackets.getModule("file/FileUtils"),
        LanguageManager     = brackets.getModule("language/LanguageManager"),
        PreferencesManager  = brackets.getModule("preferences/PreferencesManager"),
        ProjectManager      = brackets.getModule("project/ProjectManager"),
        Strings             = brackets.getModule("strings"),
        StringUtils         = brackets.getModule("utils/StringUtils");

    var HintUtils           = require("HintUtils"),
        MessageIds          = require("MessageIds"),
        Preferences         = require("Preferences");

    var ternEnvironment     = [],
        pendingTernRequests = {},
        builtinLibraryNames = [],
        isDocumentDirty     = false,
        _hintCount          = 0,
        currentWorker       = null,
        documentChanges     = null,     // bounds of document changes
        preferences         = null,
        deferredPreferences = null;

    var MAX_HINTS           = 30,  // how often to reset the tern server
        LARGE_LINE_CHANGE   = 100,
        LARGE_LINE_COUNT    = 10000,
        OFFSET_ZERO         = {line: 0, ch: 0};

    var config = {};

    /**
     *  An array of library names that contain JavaScript builtins definitions.
     *
     * @return {Array.<string>} - array of library  names.
     */
    function getBuiltins() {
        return builtinLibraryNames;
    }

    /**
     * Read in the json files that have type information for the builtins, dom,etc
     */
    function initTernEnv() {
        function loadDef(defJSON) {
            var library = JSON.parse(defJSON);
            builtinLibraryNames.push(library["!name"]);
            ternEnvironment.push(library);
        }

        require([
            "text!thirdparty/tern/defs/ecma5.json",
            "text!thirdparty/tern/defs/browser.json"
        ],
        function(ecma5, browser) {
            loadDef(ecma5);
            loadDef(browser);
        });
    }

    initTernEnv();

    /**
     *  Init preferences from a file in the project root or builtin
     *  defaults if no file is found;
     *
     *  @param {string=} projectRootPath - new project root path. Only needed
     *  for unit tests.
     */
    function initPreferences(projectRootPath) {

        // Reject the old preferences if they have not completed.
        if (deferredPreferences && deferredPreferences.state() === "pending") {
            deferredPreferences.reject();
        }

        deferredPreferences = $.Deferred();
        var pr = ProjectManager.getProjectRoot();

        // Open preferences relative to the project root
        // Normally there is a project root, but for unit tests we need to
        // pass in a project root.
        if (pr) {
            projectRootPath = pr.fullPath;
        } else if (!projectRootPath) {
            console.log("initPreferences: projectRootPath has no value");
        }

        var path = projectRootPath + Preferences.FILE_NAME;

        FileSystem.resolve(path, function (err, file) {
            if (!err) {
                FileUtils.readAsText(file).done(function (text) {
                    var configObj = null;
                    try {
                        configObj = JSON.parse(text);
                    } catch (e) {
                        // continue with null configObj which will result in
                        // default settings.
                        console.log("Error parsing preference file: " + path);
                        if (e instanceof SyntaxError) {
                            console.log(e.message);
                        }
                    }
                    preferences = new Preferences(configObj);
                    deferredPreferences.resolve();
                }).fail(function (error) {
                    preferences = new Preferences();
                    deferredPreferences.resolve();
                });
            } else {
                preferences = new Preferences();
                deferredPreferences.resolve();
            }
        });
    }

    /**
     * Will initialize preferences only if they do not exist.
     *
     */
    function ensurePreferences() {
        if (!deferredPreferences) {
            initPreferences();
        }
    }

    /**
     * Send a message to the tern worker - if the worker is being initialized,
     * the message will not be posted until initialization is complete
     */
    function postMessage(msg) {
        if (currentWorker) {
            currentWorker.postMessage(msg);
        }
    }

    /**
     * Test if the directory should be excluded from analysis.
     *
     * @param {!string} path - full directory path.
     * @return {boolean} true if excluded, false otherwise.
     */
    function isDirectoryExcluded(path) {
        var excludes = preferences.getExcludedDirectories();

        if (!excludes) {
            return false;
        }

        var testPath = ProjectManager.makeProjectRelativeIfPossible(path);
        testPath = FileUtils.stripTrailingSlash(testPath);

        return excludes.test(testPath);
    }

    /**
     * Test if the file path is in current editor
     *
     * @param {string} filePath file path to test for exclusion.
     * @return {boolean} true if in editor, false otherwise.
     */
    function isFileBeingEdited(filePath) {
        var currentEditor   = EditorManager.getActiveEditor(),
            currentDoc      = currentEditor && currentEditor.document;

        return (currentDoc && currentDoc.file.fullPath === filePath);
    }

    /**
     * Test if the file path is an internal exclusion.
     *
     * @param {string} path file path to test for exclusion.
     * @return {boolean} true if excluded, false otherwise.
     */
    function isFileExcludedInternal(path) {
        // The detectedExclusions are files detected to be troublesome with current versions of Tern.
        // detectedExclusions is an array of full paths.
        var detectedExclusions = PreferencesManager.get("jscodehints.detectedExclusions") || [];
        if (detectedExclusions && detectedExclusions.indexOf(path) !== -1) {
            return true;
        }

        return false;
    }

    /**
     * Test if the file should be excluded from analysis.
     *
     * @param {!File} file - file to test for exclusion.
     * @return {boolean} true if excluded, false otherwise.
     */
    function isFileExcluded(file) {
        if (file.name[0] === ".") {
            return true;
        }

        var languageID = LanguageManager.getLanguageForPath(file.fullPath).getId();
        if (languageID !== HintUtils.LANGUAGE_ID) {
            return true;
        }

        var excludes = preferences.getExcludedFiles();
        if (excludes && excludes.test(file.name)) {
            return true;
        }

        if (isFileExcludedInternal(file.fullPath)) {
            return true;
        }

        return false;
    }

    /**
     * Add a pending request waiting for the tern-worker to complete.
     * If file is a detected exclusion, then reject request.
     *
     * @param {string} file - the name of the file
     * @param {{line: number, ch: number}} offset - the offset into the file the request is for
     * @param {string} type - the type of request
     * @return {jQuery.Promise} - the promise for the request
     */
    function addPendingRequest(file, offset, type) {
        var requests,
            key = file + "@" + offset.line + "@" + offset.ch,
            $deferredRequest;

        // Reject detected exclusions
        if (isFileExcludedInternal(file)) {
            return (new $.Deferred()).reject().promise();
        }

        if (_.has(pendingTernRequests, key)) {
            requests = pendingTernRequests[key];
        } else {
            requests = {};
            pendingTernRequests[key] = requests;
        }

        if (_.has(requests, type)) {
            $deferredRequest = requests[type];
        } else {
            requests[type] = $deferredRequest = new $.Deferred();
        }
        return $deferredRequest.promise();
    }

    /**
     * Get any pending $.Deferred object waiting on the specified file and request type
     * @param {string} file - the file
     * @param {{line: number, ch: number}} offset - the offset into the file the request is for
     * @param {string} type - the type of request
     * @return {jQuery.Deferred} - the $.Deferred for the request
     */
    function getPendingRequest(file, offset, type) {
        var key = file + "@" + offset.line + "@" + offset.ch;
        if (_.has(pendingTernRequests, key)) {
            var requests = pendingTernRequests[key],
                requestType = requests[type];

            delete pendingTernRequests[key][type];

            if (!Object.keys(requests).length) {
                delete pendingTernRequests[key];
            }

            return requestType;
        }
    }

    /**
     * @param {string} file a relative path
     * @return {string} returns the path we resolved when we tried to parse the file, or undefined
     */
    function getResolvedPath(file) {
        return currentWorker.getResolvedPath(file);
    }

    /**
     * Get a Promise for the definition from TernJS, for the file & offset passed in.
     * @param {{type: string, name: string, offsetLines: number, text: string}} fileInfo
     * - type of update, name of file, and the text of the update.
     * For "full" updates, the whole text of the file is present. For "part" updates,
     * the changed portion of the text. For "empty" updates, the file has not been modified
     * and the text is empty.
     * @param {{line: number, ch: number}} offset - the offset in the file the hints should be calculate at
     * @return {jQuery.Promise} - a promise that will resolve to definition when
     *      it is done
     */
    function getJumptoDef(fileInfo, offset) {
        postMessage({
            type: MessageIds.TERN_JUMPTODEF_MSG,
            fileInfo: fileInfo,
            offset: offset
        });

        return addPendingRequest(fileInfo.name, offset, MessageIds.TERN_JUMPTODEF_MSG);
    }

    /**
     * check to see if the text we are sending to Tern is too long.
     * @param {string} the text to check
     * @return {string} the text, or the empty text if the original was too long
     */
    function filterText(text) {
        var newText = text;
        if (text.length > preferences.getMaxFileSize()) {
            newText = "";
        }
        return newText;
    }

    /**
     * Get the text of a document, applying any size restrictions
     * if necessary
     * @param {Document} document - the document to get the text from
     * @return {string} the text, or the empty text if the original was too long
     */
    function getTextFromDocument(document) {
        var text = document.getText();
        text = filterText(text);
        return text;
    }

    /**
     * Request Jump-To-Definition from Tern.
     *
     * @param {session} session - the session
     * @param {Document} document - the document
     * @param {{line: number, ch: number}} offset - the offset into the document
     * @return {jQuery.Promise} - The promise will not complete until tern
     *      has completed.
     */
    function requestJumptoDef(session, document, offset) {
        var path    = document.file.fullPath,
            fileInfo = {type: MessageIds.TERN_FILE_INFO_TYPE_FULL,
                name: path,
                offsetLines: 0,
                text: filterText(session.getJavascriptText())};

        var ternPromise = getJumptoDef(fileInfo, offset);

        return {promise: ternPromise};
    }

    /**
     * Handle the response from the tern web worker when
     * it responds with the definition
     *
     * @param response - the response from the worker
     */
    function handleJumptoDef(response) {

        var file = response.file,
            offset = response.offset;

        var $deferredJump = getPendingRequest(file, offset, MessageIds.TERN_JUMPTODEF_MSG);

        if ($deferredJump) {
            response.fullPath = getResolvedPath(response.resultFile);
            $deferredJump.resolveWith(null, [response]);
        }
    }

    /**
     * Get a Promise for the completions from TernJS, for the file & offset passed in.
     *
     * @param {{type: string, name: string, offsetLines: number, text: string}} fileInfo
     * - type of update, name of file, and the text of the update.
     * For "full" updates, the whole text of the file is present. For "part" updates,
     * the changed portion of the text. For "empty" updates, the file has not been modified
     * and the text is empty.
     * @param {{line: number, ch: number}} offset - the offset in the file the hints should be calculate at
     * @param {boolean} isProperty - true if getting a property hint,
     * otherwise getting an identifier hint.
     * @return {jQuery.Promise} - a promise that will resolve to an array of completions when
     *      it is done
     */
    function getTernHints(fileInfo, offset, isProperty) {

        /**
         *  If the document is large and we have modified a small portions of it that
         *  we are asking hints for, then send a partial document.
         */
        postMessage({
            type: MessageIds.TERN_COMPLETIONS_MSG,
            fileInfo: fileInfo,
            offset: offset,
            isProperty: isProperty
        });

        return addPendingRequest(fileInfo.name, offset, MessageIds.TERN_COMPLETIONS_MSG);
    }

    /**
     * Get a Promise for the function type from TernJS.
     * @param {{type: string, name: string, offsetLines: number, text: string}} fileInfo
     * - type of update, name of file, and the text of the update.
     * For "full" updates, the whole text of the file is present. For "part" updates,
     * the changed portion of the text. For "empty" updates, the file has not been modified
     * and the text is empty.
     * @param {{line:number, ch:number}} offset - the line, column info for what we want the function type of.
     * @return {jQuery.Promise} - a promise that will resolve to the function type of the function being called.
     */
    function getTernFunctionType(fileInfo, offset) {
        postMessage({
            type: MessageIds.TERN_CALLED_FUNC_TYPE_MSG,
            fileInfo: fileInfo,
            offset: offset
        });

        return addPendingRequest(fileInfo.name, offset, MessageIds.TERN_CALLED_FUNC_TYPE_MSG);
    }

    /**
     *  Given a starting and ending position, get a code fragment that is self contained
     *  enough to be compiled.
     *
     * @param {!Session} session - the current session
     * @param {{line: number, ch: number}} start - the starting position of the changes
     * @return {{type: string, name: string, offsetLines: number, text: string}}
     */
    function getFragmentAround(session, start) {
        var minIndent = null,
            minLine   = null,
            endLine,
            cm        = session.editor._codeMirror,
            tabSize   = cm.getOption("tabSize"),
            document  = session.editor.document,
            p,
            min,
            indent,
            line;

        // expand range backwards
        for (p = start.line - 1, min = Math.max(0, p - 100); p >= min; --p) {
            line = session.getLine(p);
            var fn = line.search(/\bfunction\b/);

            if (fn >= 0) {
                indent = CodeMirror.countColumn(line, null, tabSize);
                if (minIndent === null || minIndent > indent) {
                    if (session.getToken({line: p, ch: fn + 1}).type === "keyword") {
                        minIndent = indent;
                        minLine = p;
                    }
                }
            }
        }

        if (minIndent === null) {
            minIndent = 0;
        }

        if (minLine === null) {
            minLine = min;
        }

        var max = Math.min(cm.lastLine(), start.line + 100),
            endCh = 0;

        for (endLine = start.line + 1; endLine < max; ++endLine) {
            line = cm.getLine(endLine);

            if (line.length > 0) {
                indent = CodeMirror.countColumn(line, null, tabSize);
                if (indent <= minIndent) {
                    endCh = line.length;
                    break;
                }
            }
        }

        var from = {line: minLine, ch: 0},
            to   = {line: endLine, ch: endCh};

        return {type: MessageIds.TERN_FILE_INFO_TYPE_PART,
            name: document.file.fullPath,
            offsetLines: from.line,
            text: document.getRange(from, to)};
    }

    /**
     * Get an object that describes what tern needs to know about the updated
     * file to produce a hint. As a side-effect of this calls the document
     * changes are reset.
     *
     * @param {!Session} session - the current session
     * @param {boolean=} preventPartialUpdates - if true, disallow partial updates.
     * Optional, defaults to false.
     * @return {{type: string, name: string, offsetLines: number, text: string}}
     */
    function getFileInfo(session, preventPartialUpdates) {
        var start = session.getCursor(),
            end = start,
            document = session.editor.document,
            path = document.file.fullPath,
            isHtmlFile = LanguageManager.getLanguageForPath(path).getId() === "html",
            result;

        if (isHtmlFile) {
            result = {type: MessageIds.TERN_FILE_INFO_TYPE_FULL,
                name: path,
                text: session.getJavascriptText()};
        } else if (!documentChanges) {
            result = {type: MessageIds.TERN_FILE_INFO_TYPE_EMPTY,
                name: path,
                text: ""};
        } else if (!preventPartialUpdates && session.editor.lineCount() > LARGE_LINE_COUNT &&
                (documentChanges.to - documentChanges.from < LARGE_LINE_CHANGE) &&
                documentChanges.from <= start.line &&
                documentChanges.to > end.line) {
            result = getFragmentAround(session, start);
        } else {
            result = {type: MessageIds.TERN_FILE_INFO_TYPE_FULL,
                name: path,
                text: getTextFromDocument(document)};
        }

        documentChanges = null;
        return result;
    }

    /**
     *  Get the current offset. The offset is adjusted for "part" updates.
     *
     * @param {!Session} session - the current session
     * @param {{type: string, name: string, offsetLines: number, text: string}} fileInfo
     * - type of update, name of file, and the text of the update.
     * For "full" updates, the whole text of the file is present. For "part" updates,
     * the changed portion of the text. For "empty" updates, the file has not been modified
     * and the text is empty.
     * @param {{line: number, ch: number}=} offset - the default offset (optional). Will
     * use the cursor if not provided.
     * @return {{line: number, ch: number}}
     */
    function getOffset(session, fileInfo, offset) {
        var newOffset;

        if (offset) {
            newOffset = {line: offset.line, ch: offset.ch};
        } else {
            newOffset = session.getCursor();
        }

        if (fileInfo.type === MessageIds.TERN_FILE_INFO_TYPE_PART) {
            newOffset.line = Math.max(0, newOffset.line - fileInfo.offsetLines);
        }

        return newOffset;
    }

    /**
     * Get a Promise for all of the known properties from TernJS, for the directory and file.
     * The properties will be used as guesses in tern.
     * @param {Session} session - the active hinting session
     * @param {Document} document - the document for which scope info is
     *      desired
     * @return {jQuery.Promise} - The promise will not complete until the tern
     *      request has completed.
     */
    function requestGuesses(session, document) {
        var $deferred = $.Deferred(),
            fileInfo = getFileInfo(session),
            offset = getOffset(session, fileInfo);

        postMessage({
            type: MessageIds.TERN_GET_GUESSES_MSG,
            fileInfo: fileInfo,
            offset: offset
        });

        var promise = addPendingRequest(fileInfo.name, offset, MessageIds.TERN_GET_GUESSES_MSG);
        promise.done(function (guesses) {
            session.setGuesses(guesses);
            $deferred.resolve();
        }).fail(function () {
            $deferred.reject();
        });

        return $deferred.promise();
    }

    /**
     * Handle the response from the tern web worker when
     * it responds with the list of completions
     *
     * @param {{file: string, offset: {line: number, ch: number}, completions:Array.<string>,
     *          properties:Array.<string>}} response - the response from the worker
     */
    function handleTernCompletions(response) {

        var file = response.file,
            offset = response.offset,
            completions = response.completions,
            properties = response.properties,
            fnType  = response.fnType,
            type = response.type,
            error = response.error,
            $deferredHints = getPendingRequest(file, offset, type);

        if ($deferredHints) {
            if (error) {
                $deferredHints.reject();
            } else if (completions) {
                $deferredHints.resolveWith(null, [{completions: completions}]);
            } else if (properties) {
                $deferredHints.resolveWith(null, [{properties: properties}]);
            } else if (fnType) {
                $deferredHints.resolveWith(null, [fnType]);
            }
        }
    }

    /**
     * Handle the response from the tern web worker when
     * it responds to the get guesses message.
     *
     * @param {{file: string, type: string, offset: {line: number, ch: number},
     *      properties: Array.<string>}} response -
     *      the response from the worker contains the guesses for a
     *      property lookup.
     */
    function handleGetGuesses(response) {
        var path = response.file,
            type = response.type,
            offset = response.offset,
            $deferredHints = getPendingRequest(path, offset, type);

        if ($deferredHints) {
            $deferredHints.resolveWith(null, [response.properties]);
        }
    }

    /**
     * Handle the response from the tern web worker when
     * it responds to the update file message.
     *
     * @param {{path: string, type: string}} response - the response from the worker
     */
    function handleUpdateFile(response) {

        var path = response.path,
            type = response.type,
            $deferredHints = getPendingRequest(path, OFFSET_ZERO, type);

        if ($deferredHints) {
            $deferredHints.resolve();
        }
    }

    /**
     * Handle timed out inference
     *
     * @param {{path: string, type: string}} response - the response from the worker
     */
    function handleTimedOut(response) {

        var detectedExclusions  = PreferencesManager.get("jscodehints.detectedExclusions") || [],
            filePath            = response.file;

        // Don't exclude the file currently being edited
        if (isFileBeingEdited(filePath)) {
            return;
        }

        // Handle file that is already excluded
        if (detectedExclusions.indexOf(filePath) !== -1) {
            console.log("JavaScriptCodeHints.handleTimedOut: file already in detectedExclusions array timed out: " + filePath);
            return;
        }

        // Save detected exclusion in project prefs so no further time is wasted on it
        detectedExclusions.push(filePath);
        PreferencesManager.set("jscodehints.detectedExclusions", detectedExclusions, { location: { scope: "project" } });

        // Show informational dialog
        Dialogs.showModalDialog(
            DefaultDialogs.DIALOG_ID_INFO,
            Strings.DETECTED_EXCLUSION_TITLE,
            StringUtils.format(
                Strings.DETECTED_EXCLUSION_INFO,
                StringUtils.breakableUrl(filePath)
            ),
            [
                {
                    className : Dialogs.DIALOG_BTN_CLASS_PRIMARY,
                    id        : Dialogs.DIALOG_BTN_OK,
                    text      : Strings.OK
                }
            ]
        );
    }

    /**
     * Encapsulate all the logic to talk to the worker thread.  This will create
     * a new instance of a TernWorker, which the rest of the hinting code can use to talk
     * to the worker, without worrying about initialization, priming the pump, etc.
     *
     */
    function TernWorker() {
        var ternPromise         = null,
            addFilesPromise     = null,
            rootTernDir         = null,
            projectRoot         = null,
            stopAddingFiles     = false,
            resolvedFiles       = {},       // file -> resolved file
            numInitialFiles     = 0,
            numResolvedFiles    = 0,
            numAddedFiles       = 0,
            _ternWorker         = null;

        /**
         * @param {string} file a relative path
         * @return {string} returns the path we resolved when we tried to parse the file, or undefined
         */
        function getResolvedPath(file) {
            return resolvedFiles[file];
        }

        /**
         *  Determine whether the current set of files are using modules to pull in
         *  additional files.
         *
         * @return {boolean} - true if more files than the current directory have
         * been read in.
         */
        function usingModules() {
            return numInitialFiles !== numResolvedFiles;
        }

        /**
         * Send a message to the tern worker - if the worker is being initialized,
         * the message will not be posted until initialization is complete
         */
        function postMessage(msg) {
            addFilesPromise.done(function (ternWorker) {
                // If an error came up during file handling, bail out now
                if (!ternWorker) {
                    return;
                }

                if (config.debug) {
                    console.debug("Sending message", msg);
                }
                ternWorker.postMessage(msg);
            });
        }

        /**
         * Send a message to the tern worker - this is only for messages that
         * need to be sent before and while the addFilesPromise is being resolved.
         */
        function _postMessageByPass(msg) {
            ternPromise.done(function (ternWorker) {
                if (config.debug) {
                    console.debug("Sending message", msg);
                }
                ternWorker.postMessage(msg);
            });
        }

        /**
         *  Update tern with the new contents of a given file.
         *
         * @param {Document} document - the document to update
         * @return {jQuery.Promise} - the promise for the request
         */
        function updateTernFile(document) {
            var path  = document.file.fullPath;

            _postMessageByPass({
                type       : MessageIds.TERN_UPDATE_FILE_MSG,
                path       : path,
                text       : getTextFromDocument(document)
            });

            return addPendingRequest(path, OFFSET_ZERO, MessageIds.TERN_UPDATE_FILE_MSG);
        }

        /**
         * Handle a request from the worker for text of a file
         *
         * @param {{file:string}} request - the request from the worker.  Should be an Object containing the name
         *      of the file tern wants the contents of
         */
        function handleTernGetFile(request) {

            function replyWith(name, txt) {
                _postMessageByPass({
                    type: MessageIds.TERN_GET_FILE_MSG,
                    file: name,
                    text: txt
                });
            }

            var name = request.file;

            /**
             * Helper function to get the text of a given document and send it to tern.
             * If DocumentManager successfully gets the file's text then we'll send it to the tern worker.
             * The Promise for getDocumentText() is returned so that custom fail functions can be used.
             *
             * @param {string} filePath - the path of the file to get the text of
             * @return {jQuery.Promise} - the Promise returned from DocumentMangaer.getDocumentText()
             */
            function getDocText(filePath) {
                if (!FileSystem.isAbsolutePath(filePath)) {
                    return (new $.Deferred()).reject().promise();
                }

                var file = FileSystem.getFileForPath(filePath),
                    promise = DocumentManager.getDocumentText(file);

                promise.done(function (docText) {
                    resolvedFiles[name] = filePath;
                    numResolvedFiles++;
                    replyWith(name, filterText(docText));
                });
                return promise;
            }

            /**
             * Helper function to find any files in the project that end with the
             * name we are looking for.  This is so we can find requirejs modules
             * when the baseUrl is unknown, or when the project root is not the same
             * as the script root (e.g. if you open the 'brackets' dir instead of 'brackets/src' dir).
             */
            function findNameInProject() {
                // check for any files in project that end with the right path.
                var fileName = name.substring(name.lastIndexOf("/") + 1);

                function _fileFilter(entry) {
                    return entry.name === fileName;
                }

                ProjectManager.getAllFiles(_fileFilter).done(function (files) {
                    var file;
                    files = files.filter(function (file) {
                        var pos = file.fullPath.length - name.length;
                        return pos === file.fullPath.lastIndexOf(name);
                    });

                    if (files.length === 1) {
                        file = files[0];
                    }
                    if (file) {
                        getDocText(file.fullPath).fail(function () {
                            replyWith(name, "");
                        });
                    } else {
                        replyWith(name, "");
                    }
                });
            }

            if (!isFileExcludedInternal(name)) {
                getDocText(name).fail(function () {
                    getDocText(rootTernDir + name).fail(function () {
                        // check relative to project root
                        getDocText(projectRoot + name)
                            // last look for any files that end with the right path
                            // in the project
                            .fail(findNameInProject);
                    });
                });
            }
        }

        /**
         *  Prime the pump for a fast first lookup.
         *
         * @param {string} path - full path of file
         * @return {jQuery.Promise} - the promise for the request
         */
        function primePump(path) {
            _postMessageByPass({
                type        : MessageIds.TERN_PRIME_PUMP_MSG,
                path        : path
            });

            return addPendingRequest(path, OFFSET_ZERO, MessageIds.TERN_PRIME_PUMP_MSG);
        }

        /**
         * Handle the response from the tern web worker when
         * it responds to the prime pump message.
         *
         * @param {{path: string, type: string}} response - the response from the worker
         */
        function handlePrimePumpCompletion(response) {

            var path = response.path,
                type = response.type,
                $deferredHints = getPendingRequest(path, OFFSET_ZERO, type);

            if ($deferredHints) {
                $deferredHints.resolve();
            }
        }

        /**
         *  Add new files to tern, keeping any previous files.
         *  The tern server must be initialized before making
         *  this call.
         *
         * @param {Array.<string>} files - array of file to add to tern.
         * @return {boolean} - true if more files may be added, false if maximum has been reached.
         */
        function addFilesToTern(files) {
            // limit the number of files added to tern.
            var maxFileCount = preferences.getMaxFileCount();
            if (numResolvedFiles + numAddedFiles < maxFileCount) {
                var available = maxFileCount - numResolvedFiles - numAddedFiles;

                if (available < files.length) {
                    files = files.slice(0, available);
                }

                numAddedFiles += files.length;
                ternPromise.done(function (worker) {
                    var msg = {
                        type        : MessageIds.TERN_ADD_FILES_MSG,
                        files       : files
                    };

                    if (config.debug) {
                        console.debug("Sending message", msg);
                    }
                    worker.postMessage(msg);
                });

            } else {
                stopAddingFiles = true;
            }

            return stopAddingFiles;
        }

        /**
         *  Add the files in the directory and subdirectories of a given directory
         *  to tern.
         *
         * @param {string} dir - the root directory to add.
         * @param {function ()} doneCallback - called when all files have been
         * added to tern.
         */
        function addAllFilesAndSubdirectories(dir, doneCallback) {
            FileSystem.resolve(dir, function (err, directory) {
                function visitor(entry) {
                    if (entry.isFile) {
                        if (!isFileExcluded(entry)) { // ignore .dotfiles and non-.js files
                            addFilesToTern([entry.fullPath]);
                        }
                    } else {
                        return !isDirectoryExcluded(entry.fullPath) &&
                            entry.name.indexOf(".") !== 0 &&
                            !stopAddingFiles;
                    }
                }

                if (err) {
                    return;
                }

                if (dir === FileSystem.getDirectoryForPath(rootTernDir)) {
                    doneCallback();
                    return;
                }

                directory.visit(visitor, doneCallback);
            });
        }

        /**
         * Init the web worker that does all the code hinting work.
         *
         * If a worker already exists, then this will terminate that worker and
         * start a new worker - this helps alleviate leaks that may be ocurring in
         * the code that the worker runs.
         */
        function initTernWorker() {
            if (_ternWorker) {
                _ternWorker.terminate();
            }
            var workerDeferred = $.Deferred();
            ternPromise = workerDeferred.promise();
            var path = ExtensionUtils.getModulePath(module, "tern-worker.js");
            _ternWorker = new Worker(path);

            _ternWorker.addEventListener("message", function (e) {
                if (config.debug) {
                    console.debug("Message received", e);
                }

                var response = e.data,
                    type = response.type;

                if (type === MessageIds.TERN_COMPLETIONS_MSG ||
                        type === MessageIds.TERN_CALLED_FUNC_TYPE_MSG) {
                    // handle any completions the worker calculated
                    handleTernCompletions(response);
                } else if (type === MessageIds.TERN_GET_FILE_MSG) {
                    // handle a request for the contents of a file
                    handleTernGetFile(response);
                } else if (type === MessageIds.TERN_JUMPTODEF_MSG) {
                    handleJumptoDef(response);
                } else if (type === MessageIds.TERN_PRIME_PUMP_MSG) {
                    handlePrimePumpCompletion(response);
                } else if (type === MessageIds.TERN_GET_GUESSES_MSG) {
                    handleGetGuesses(response);
                } else if (type === MessageIds.TERN_UPDATE_FILE_MSG) {
                    handleUpdateFile(response);
                } else if (type === MessageIds.TERN_INFERENCE_TIMEDOUT) {
                    handleTimedOut(response);
                } else if (type === MessageIds.TERN_WORKER_READY) {
                    workerDeferred.resolveWith(null, [_ternWorker]);
                } else {
                    console.log("Worker: " + (response.log || response));
                }
            });

            // Set the initial configuration for the worker
            _ternWorker.postMessage({
                type: MessageIds.SET_CONFIG,
                config: config
            });
        }
        /**
         * Create a new tern server.
         */
        function initTernServer(dir, files) {
            initTernWorker();
            numResolvedFiles = 0;
            numAddedFiles = 0;
            stopAddingFiles = false;
            numInitialFiles = files.length;

            ternPromise.done(function (worker) {
                var msg = {
                    type        : MessageIds.TERN_INIT_MSG,
                    dir         : dir,
                    files       : files,
                    env         : ternEnvironment,
                    timeout     : PreferencesManager.get("jscodehints.inferenceTimeout")
                };

                if (worker) {
                    if (config.debug) {
                        console.debug("Sending message", msg);
                    }
                    worker.postMessage(msg);
                } else {
                    if (config.debug) {
                        console.debug("Worker null. Cannot send message", msg);
                    }
                }
            });
            rootTernDir = dir + "/";
        }

        /**
         *  We can skip tern initialization if we are opening a file that has
         *  already been added to tern.
         *
         * @param {string} newFile - full path of new file being opened in the editor.
         * @return {boolean} - true if tern initialization should be skipped,
         * false otherwise.
         */
        function canSkipTernInitialization(newFile) {
            return resolvedFiles[newFile] !== undefined;
        }

        /**
         *  Do the work to initialize a code hinting session.
         *
         * @param {Session} session - the active hinting session (TODO: currently unused)
         * @param {!Document} document - the document the editor has changed to
         * @param {?Document} previousDocument - the document the editor has changed from
         */
        function doEditorChange(session, document, previousDocument) {
            var file        = document.file,
                path        = file.fullPath,
                dir         = file.parentPath,
                pr;

            var addFilesDeferred = $.Deferred();

            documentChanges = null;
            addFilesPromise = addFilesDeferred.promise();
            pr = ProjectManager.getProjectRoot() ? ProjectManager.getProjectRoot().fullPath : null;

            // avoid re-initializing tern if possible.
            if (canSkipTernInitialization(path)) {

                // update the previous document in tern to prevent stale files.
                if (isDocumentDirty && previousDocument) {
                    var updateFilePromise = updateTernFile(previousDocument);
                    updateFilePromise.done(function () {
                        primePump(path);
                        addFilesDeferred.resolveWith(null, [_ternWorker]);
                    });
                } else {
                    addFilesDeferred.resolveWith(null, [_ternWorker]);
                }

                isDocumentDirty = false;
                return;
            }

            isDocumentDirty = false;
            resolvedFiles = {};
            projectRoot = pr;

            ensurePreferences();
            deferredPreferences.done(function () {
                FileSystem.resolve(dir, function (err, directory) {
                    if (err) {
                        console.error("Error resolving", dir);
                        addFilesDeferred.resolveWith(null);
                        return;
                    }

                    directory.getContents(function (err, contents) {
                        if (err) {
                            console.error("Error getting contents for", directory);
                            addFilesDeferred.resolveWith(null);
                            return;
                        }

                        var files = contents
                            .filter(function (entry) {
                                return entry.isFile && !isFileExcluded(entry);
                            })
                            .map(function (entry) {
                                return entry.fullPath;
                            });

                        initTernServer(dir, files);

                        var hintsPromise = primePump(path);
                        hintsPromise.done(function () {
                            if (!usingModules()) {
                                // Read the subdirectories of the new file's directory.
                                // Read them first in case there are too many files to
                                // read in the project.
                                addAllFilesAndSubdirectories(dir, function () {
                                    // If the file is in the project root, then read
                                    // all the files under the project root.
                                    var currentDir = (dir + "/");
                                    if (projectRoot && currentDir !== projectRoot &&
                                            currentDir.indexOf(projectRoot) === 0) {
                                        addAllFilesAndSubdirectories(projectRoot, function () {
                                            // prime the pump again but this time don't wait
                                            // for completion.
                                            primePump(path);

                                            addFilesDeferred.resolveWith(null, [_ternWorker]);
                                        });
                                    } else {
                                        addFilesDeferred.resolveWith(null, [_ternWorker]);
                                    }
                                });
                            } else {
                                addFilesDeferred.resolveWith(null, [_ternWorker]);
                            }
                        });
                    });
                });
            });
        }

        /**
         * Called each time a new editor becomes active.
         *
         * @param {Session} session - the active hinting session (TODO: currently unused by doEditorChange())
         * @param {!Document} document - the document of the editor that has changed
         * @param {?Document} previousDocument - the document of the editor is changing from
         */
        function handleEditorChange(session, document, previousDocument) {
            if (addFilesPromise === null) {
                doEditorChange(session, document, previousDocument);
            } else {
                addFilesPromise.done(function () {
                    doEditorChange(session, document, previousDocument);
                });
            }
        }

        /**
         * Do some cleanup when a project is closed.
         *
         * We can clean up the web worker we use to calculate hints now, since
         * we know we will need to re-init it in any new project that is opened.
         */
        function closeWorker() {
            function terminateWorker() {
                var worker = _ternWorker;

                // Worker can be null if an error condition came up previously
                if (!worker) {
                    return;
                }
                setTimeout(function () {
                    // give pending requests a chance to finish
                    worker.terminate();
                    worker = null;
                }, 1000);
                _ternWorker = null;
                resolvedFiles = {};
            }

            if (_ternWorker) {
                if (addFilesPromise) {
                    // If we're in the middle of added files, don't terminate
                    // until we're done or we might get NPEs
                    addFilesPromise.done(terminateWorker).fail(terminateWorker);
                } else {
                    terminateWorker();
                }
            }
        }

        function whenReady(func) {
            addFilesPromise.done(func);
        }

        this.closeWorker = closeWorker;
        this.handleEditorChange = handleEditorChange;
        this.postMessage = postMessage;
        this.getResolvedPath = getResolvedPath;
        this.whenReady = whenReady;

        return this;
    }

    var resettingDeferred = null;

    /**
     * reset the tern worker thread, if necessary.
     *
     * To avoid memory leaks in the worker thread we periodically kill
     * the web worker instance, and start a new one.  To avoid a performance
     * hit when we do this we start up a new worker, and don't kill the old
     * one unitl the new one is initialized.
     *
     * During debugging, you can turn this automatic resetting behavior off
     * by running this in the console:
     * brackets._configureJSCodeHints({ noReset: true })
     *
     * This function is also used in unit testing with the "force" flag to
     * reset the worker for each test to start with a clean environment.
     *
     * @param {Session} session
     * @param {Document} document
     * @param {boolean} force true to force a reset regardless of how long since the last one
     * @return {Promise} Promise resolved when the worker is ready.
     *                   The new (or current, if there was no reset) worker is passed to the callback.
     */
    function _maybeReset(session, document, force) {
        var newWorker;
        // if we're in the middle of a reset, don't have to check
        // the new worker will be online soon
        if (!resettingDeferred) {

            // We don't reset if the debugging flag is set
            // because it's easier to debug if the worker isn't
            // getting shut down all the time.
            if (force || (!config.noReset && ++_hintCount > MAX_HINTS)) {
                if (config.debug) {
                    console.debug("Resetting tern worker");
                }

                resettingDeferred = new $.Deferred();
                newWorker = new TernWorker();
                newWorker.handleEditorChange(session, document, null);
                newWorker.whenReady(function () {
                    // tell the old worker to shut down
                    currentWorker.closeWorker();
                    currentWorker = newWorker;
                    resettingDeferred.resolve(currentWorker);
                    // all done reseting
                    resettingDeferred = null;
                });
                _hintCount = 0;
            } else {
                var d = new $.Deferred();
                d.resolve(currentWorker);
                return d.promise();
            }
        }

        return resettingDeferred.promise();
    }

    /**
     * Request a parameter hint from Tern.
     *
     * @param {Session} session - the active hinting session
     * @param {{line: number, ch: number}} functionOffset - the offset of the function call.
     * @return {jQuery.Promise} - The promise will not complete until the
     *      hint has completed.
     */
    function requestParameterHint(session, functionOffset) {
        var $deferredHints = $.Deferred(),
            fileInfo = getFileInfo(session, true),
            offset = getOffset(session, fileInfo, functionOffset),
            fnTypePromise = getTernFunctionType(fileInfo, offset);

        $.when(fnTypePromise).done(
            function (fnType) {
                session.setFnType(fnType);
                session.setFunctionCallPos(functionOffset);
                $deferredHints.resolveWith(null, [fnType]);
            }
        ).fail(function () {
            $deferredHints.reject();
        });

        return $deferredHints.promise();
    }

    /**
     * Request hints from Tern.
     *
     * Note that successive calls to getScope may return the same objects, so
     * clients that wish to modify those objects (e.g., by annotating them based
     * on some temporary context) should copy them first. See, e.g.,
     * Session.getHints().
     *
     * @param {Session} session - the active hinting session
     * @param {Document} document - the document for which scope info is
     *      desired
     * @return {jQuery.Promise} - The promise will not complete until the tern
     *      hints have completed.
     */
    function requestHints(session, document) {
        var $deferredHints = $.Deferred(),
            hintPromise,
            sessionType = session.getType(),
            fileInfo = getFileInfo(session),
            offset = getOffset(session, fileInfo, null);

        _maybeReset(session, document);

        hintPromise = getTernHints(fileInfo, offset, sessionType.property);

        $.when(hintPromise).done(
            function (completions, fnType) {
                if (completions.completions) {
                    session.setTernHints(completions.completions);
                    session.setGuesses(null);
                } else {
                    session.setTernHints([]);
                    session.setGuesses(completions.properties);
                }

                $deferredHints.resolveWith(null);
            }
        ).fail(function () {
            $deferredHints.reject();
        });

        return $deferredHints.promise();
    }

    /**
     *  Track the update area of the current document so we can tell if we can send
     *  partial updates to tern or not.
     *
     * @param {Array.<{from: {line:number, ch: number}, to: {line:number, ch: number},
     *     text: Array<string>}>} changeList - the document changes from the current change event
     */
    function trackChange(changeList) {
        var changed = documentChanges, i;
        if (changed === null) {
            documentChanges = changed = {from: changeList[0].from.line, to: changeList[0].from.line};
            if (config.debug) {
                console.debug("ScopeManager: document has changed");
            }
        }

        for (i = 0; i < changeList.length; i++) {
            var thisChange = changeList[i],
                end = thisChange.from.line + (thisChange.text.length - 1);
            if (thisChange.from.line < changed.to) {
                changed.to = changed.to - (thisChange.to.line - end);
            }

            if (end >= changed.to) {
                changed.to = end + 1;
            }

            if (changed.from > thisChange.from.line) {
                changed.from = thisChange.from.line;
            }
        }
    }

    /*
     * Called each time the file associated with the active editor changes.
     * Marks the file as being dirty.
     *
     * @param {from: {line:number, ch: number}, to: {line:number, ch: number}}
     */
    function handleFileChange(changeList) {
        isDocumentDirty = true;
        trackChange(changeList);
    }

    /**
     * Called each time a new editor becomes active.
     *
     * @param {Session} session - the active hinting session
     * @param {Document} document - the document of the editor that has changed
     * @param {?Document} previousDocument - the document of the editor is changing from
     */
    function handleEditorChange(session, document, previousDocument) {

        if (!currentWorker) {
            currentWorker = new TernWorker();
        }
        return currentWorker.handleEditorChange(session, document, previousDocument);
    }

    /**
     * Do some cleanup when a project is closed.
     *
     * We can clean up the web worker we use to calculate hints now, since
     * we know we will need to re-init it in any new project that is opened.
     */
    function handleProjectClose() {
        if (currentWorker) {
            currentWorker.closeWorker();
            currentWorker = null;
        }
    }

    /**
     *  Read in project preferences when a new project is opened.
     *  Look in the project root directory for a preference file.
     *
     *  @param {string=} projectRootPath - new project root path(optional).
     *  Only needed for unit tests.
     */
    function handleProjectOpen(projectRootPath) {
        initPreferences(projectRootPath);
    }

    /** Used to avoid timing bugs in unit tests */
    function _readyPromise() {
        return deferredPreferences;
    }

    /**
     * @private
     *
     * Update the configuration in the worker.
     */
    function _setConfig(configUpdate) {
        config = brackets._configureJSCodeHints.config;
        postMessage({
            type: MessageIds.SET_CONFIG,
            config: configUpdate
        });
    }

    exports._setConfig = _setConfig;
    exports._maybeReset = _maybeReset;
    exports.getBuiltins = getBuiltins;
    exports.getResolvedPath = getResolvedPath;
    exports.getTernHints = getTernHints;
    exports.handleEditorChange = handleEditorChange;
    exports.requestGuesses = requestGuesses;
    exports.handleFileChange = handleFileChange;
    exports.requestHints = requestHints;
    exports.requestJumptoDef = requestJumptoDef;
    exports.requestParameterHint = requestParameterHint;
    exports.handleProjectClose = handleProjectClose;
    exports.handleProjectOpen = handleProjectOpen;
    exports._readyPromise = _readyPromise;

});


text:
package ca.pfv.spmf.algorithms.sequentialpatterns.spade_spam_AGP.dataStructures;

import java.util.Comparator;

public class Item<T extends Comparable> implements Comparable<Item> {

    /**
     * Content of the item. Is implemented in a generic way in order to manage
     * several types of items.
     */
    private T id;

    /**
     * General constructor.
     * @param id Content of the item.
     */
    public Item(T id) {
        this.id = id;
    }

    /**
     * It gets the content of the item.
     * @return the content
     */
    public T getId() {
        return id;
    }

    /**
     * Get the string representation of this item
     * @return the string representation
     */
    @Override
    public String toString() {
        return "" + getId();
    }

    /**
     * Check if this item is equal to another (if their identifier are equal).
     * @param object the other item
     * @return true if yes, otherwise false
     */
    @Override
    public boolean equals(Object object) {
        if (object instanceof Item) {
            Item item = (Item) object;
            if ((item.getId().equals(this.getId()))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }

    @Override
    public int compareTo(Item i) {
        //return -id.compareTo(i.getId());
        return id.compareTo(i.getId());
    }
}

class itemComparator implements Comparator<Item> {

    @Override
    public int compare(Item o1, Item o2) {
        int value = o1.compareTo(o2);
        return -value;
    }
}

redpajama_set_name: RedPajamaGithub


text:
This feature is language-specific.
It occurs with 1 different values: `Pol`.

31 tokens (0%) have a non-empty value of `Polite`.
3 types (0%) occur at least once with a non-empty value of `Polite`.
3 lemmas (0%) occur at least once with a non-empty value of `Polite`.
The feature is used with 2 part-of-speech tags: [da-pos/PRON]() (27; 0% instances), [da-pos/DET]() (4; 0% instances).

### `PRON`

27 [da-pos/PRON]() tokens (0% of all `PRON` tokens) have a non-empty value of `Polite`.

The most frequent other feature values with which `PRON` and `Polite` co-occurred: <tt>PronType=Prs</tt> (27; 100%), <tt>Person=2</tt> (27; 100%), <tt>PartType=EMPTY</tt> (27; 100%), <tt>Number=EMPTY</tt> (27; 100%), <tt>Gender=Com</tt> (26; 96%), <tt>Case=Nom</tt> (21; 78%).

`PRON` tokens may have the following values of `Polite`:

* `Pol` (27; 100% of non-empty `Polite`): De, Dem, Deres

### `DET`

4 [da-pos/DET]() tokens (0% of all `DET` tokens) have a non-empty value of `Polite`.

The most frequent other feature values with which `DET` and `Polite` co-occurred: <tt>Gender=EMPTY</tt> (4; 100%), <tt>Poss=Yes</tt> (4; 100%), <tt>PronType=Prs</tt> (4; 100%), <tt>Number[psor]=EMPTY</tt> (4; 100%), <tt>Person=2</tt> (4; 100%), <tt>Number=EMPTY</tt> (4; 100%).

`DET` tokens may have the following values of `Polite`:

* `Pol` (4; 100% of non-empty `Polite`): Deres


text:
title:  imDialog
date:  22/10/2021
---

#### imDialog

`Womit hat Gott dich sowohl materiell als auch geistlich gesegnet?`

`Wie können wir in unserem Leben zeigen, dass wir allein Gott dienen?`

`Wie kann man Gott ganz konkret mit Herz, Seele und Kraft lieben?`

`Wie können wir dafür sorgen, dass wir alles durch die Brille unserer Liebe zu Gott sehen und tun?`

`Auf welche Weise könntest du diese Liebesbeziehung, die du zu Gott hast, an deine Kinder/zukünftigen Kinder und an Freunde und Familienmitglieder weitergeben?`

`Wie hast du erlebt, dass Liebe zu Veränderungen in deinem Verhalten geführt hat?`

`Wie können wir Gesetzlichkeit in unserem eigenen Leben und in unserer Gemeinde bekämpfen?`


text:
/*
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
*/
/*
    Created on : May 19, 2016, 4:11:30 PM
    Author     : shashikumar
*/
.dropbtn{
    background-color: grey;
    color: white;
    padding: 16px;
    font-size: 16px;
    border: none;
    cursor: pointer;
}
.dropdown{
    position: relative;
    display: inline-block;
}
.dropdown-content{
    display: none;
    position: absolute;
    background-color: blueviolet;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content a{
    color: black;
    padding: 12px;
    text-decoration: none;
    display: none;
}
.dropdown-content a:hover{
    background-color: purple
}
.dropdown:hover .dropdown-content{
    display: none
}
.dropdown:hover .dropbtn{
    background-color: hotpink;
}
.table{
    margin-left: 15px;
    border: #777 4px dashed;
}


text:
// CS 540 : HW2
// author: priyananda( shenoy@cs.wisc.edu )
// date: 5 Oct 2008
// random quote: [Pulp Fiction] The Wolf: I'm Winston Wolfe. I solve problems.
import java.util.Vector;
/**
 * Same as AlphaBetaPlayer, except that the evaluation function is different
 */
public class SHENOYPlayer extends CheckerPlayer implements CheckerBoardConstants
{
	public SHENOYPlayer(String name)
	{
		super(name);
	}
	//overridden method to compute the best next move
	public void calculateMove(int[][] bs, int whosTurn)
	{
		this.chosenMoveValue = Integer.MIN_VALUE;
		this.chosenMove = null;

		//iterative deepening. 100 is some arbitrary number which will never
		//be reached.
		for(int depth = 1 ; depth < 100 ; ++depth ){
			//this finds best solution for the given depth cutoff and
			//stores it in tempSolution/tempValue
			findBestSolutionWithinDepth(bs, whosTurn, depth);

			if(this.tempValue > this.chosenMoveValue){
				this.chosenMoveValue = this.tempValue;
				this.chosenMove = this.tempSolution;
			}
			if(Utils.debug)
				System.out.printf(
					"Done with depth limit %d\nI pruned the tree %d time(s)\n",
					depth, pruneCount
				);
		}
	}
	//depth-0 is always maximizing.
	private void findBestSolutionWithinDepth(int [][] bs,int whosTurn, int depth)
	{
		this.depthCutOff = depth;
		this.pruneCount = 0;

		this.tempSolution = null;
		this.tempValue = Integer.MIN_VALUE;

		for(Object m : Utils.getAllPossibleMoves(bs, whosTurn)){
			Move currentMove = (Move)m;
			int [][] bsnew = Utils.copyBoardState(bs);
			Utils.executeMove(whosTurn, currentMove, bsnew);
			int kidValue = alphaBetaPrune(
				bsnew,
				whosTurn,
				1, //initial depth
				Integer.MIN_VALUE, //alpha
				Integer.MAX_VALUE  //beta
			);
			if(this.tempSolution == null || kidValue > this.tempValue){
				this.tempSolution = currentMove;
				this.tempValue = kidValue;
			}
		}
	}
	//main method which implements alpha-beta minimax search
	private int alphaBetaPrune(int [][] bs,int whosTurn, int depth, int alpha, int beta)
	{
		if(depth >= this.depthCutOff)
			//reached the end of cutoff, stop
			return evaluateBoard(bs, whosTurn);

		//if i am a minimizing node, then the other player has to move.
		Vector kids = Utils.getAllPossibleMoves(bs,
			isMax(depth,whosTurn) ? whosTurn : otherPlayer(whosTurn)
		);
		if(kids.size() == 0)
			//this is a dead end. just return the current value.
			return evaluateBoard(bs, whosTurn);

		//is this node a max node or min node
		if(isMax(depth, whosTurn)){
			int i;
			for(i = 0 ; i < kids.size() && alpha < beta; ++i ){
				Move currentMove = (Move)kids.elementAt(i);
				int [][] bsnew = Utils.copyBoardState(bs);
				Utils.executeMove(whosTurn , currentMove, bsnew);
				int kidAlpha = alphaBetaPrune(bsnew,whosTurn,depth+1,alpha,beta);
				if( kidAlpha > alpha )
					alpha = kidAlpha;
			}
			pruneCount += kids.size() - i;
			return alpha;
		}else{
			int i;
			for(i = 0 ; i < kids.size() && alpha < beta; ++i ){
				Move currentMove = (Move)kids.elementAt(i);
				int [][] bsnew = Utils.copyBoardState(bs);

				//when the current node is minimizing, the other
				//player is to move.
				Utils.executeMove(
					otherPlayer(whosTurn),
					currentMove,
					bsnew
				);
				int kidBeta = alphaBetaPrune(bsnew, whosTurn,depth+1, alpha, beta);
				if( kidBeta < beta )
					beta = kidBeta;
			}
			pruneCount += kids.size() - i;
			return beta;
		}
	}

	private boolean isMax(int depth, int whosTurn)
	{
		if(depth % 2 == 0)
			//even depth is maximizing
			return true;
		else
			//odd depth is minimizing
			return false;
	}
	//this simplifies many things, like the current player always maximizes
	protected int evaluateBoard(int [][] bs,int whosTurn)
	{
		int ret = scoreCheckerBoard(bs, whosTurn);
		return (whosTurn == RED_PLAYER) ? ret : -ret;
	}
	//simple helper function to get the opposite player
	private int otherPlayer(int whosTurn)
	{
		return whosTurn == RED_PLAYER ? BLACK_PLAYER : RED_PLAYER;
	}
	//static board evaluation function
	protected int scoreCheckerBoard(int [][] bs,int whosTurn)
	{
		int redValue = 0;
		int blackValue = 0;
		for(int i = 0 ; i < Utils.BOARD_WIDTH; ++i)
			for(int j = 0; j < Utils.BOARD_HEIGHT; ++j){
				switch(bs[i][j]){
					case RED_PAWN:
						redValue += 10; //base
						redValue += isValid(i-1,j-1) + isValid(i-1,j+1); //dof
						redValue += canAttack(bs,i - 1,j - 1, i - 2, j - 2, BLACK_PLAYER) +
									canAttack(bs,i - 1,j + 1, i - 2, j + 2, BLACK_PLAYER);
					break;
					case RED_KING:
						redValue += 25; //base
						redValue += isValid(i-1,j-1) + isValid(i-1,j+1) +
									isValid(i+1,j-1) + isValid(i+1,j+1); //dof
						redValue += canAttack(bs,i - 1,j - 1, i - 2, j - 2, BLACK_PLAYER) +
									canAttack(bs,i - 1,j + 1, i - 2, j + 2, BLACK_PLAYER) +
									canAttack(bs,i + 1,j - 1, i + 2, j - 2, BLACK_PLAYER) +
									canAttack(bs,i + 1,j + 1, i + 2, j + 2, BLACK_PLAYER);
					break;
					case BLACK_PAWN:
						blackValue += 10; //base
						blackValue += isValid(i+1,j-1) + isValid(i+1,j+1); //dof
						blackValue += canAttack(bs,i + 1,j - 1, i + 2, j - 2, RED_PLAYER) +
									  canAttack(bs,i + 1,j + 1, i + 2, j + 2, RED_PLAYER);
					break;
					case BLACK_KING:
						blackValue += 25;
						blackValue += isValid(i-1,j-1) + isValid(i-1,j+1) +
									  isValid(i+1,j-1) + isValid(i+1,j+1); //dof
						blackValue += canAttack(bs,i - 1,j - 1, i - 2, j - 2, RED_PLAYER) +
									  canAttack(bs,i - 1,j + 1, i - 2, j + 2, RED_PLAYER) +
									  canAttack(bs,i + 1,j - 1, i + 2, j - 2, RED_PLAYER) +
									  canAttack(bs,i + 1,j + 1, i + 2, j + 2, RED_PLAYER);
					break;
				}
			}
		return redValue - blackValue + ((int)(Math.random() * 4) - 2);
	}
	//returns 1 if the location is valid
	private int isValid(int i,int j)
	{
		if(i >= 0 && i < BOARD_WIDTH)
			if(j >= 0 && j < BOARD_HEIGHT)
				return 1;
		return 0;
	}
	//can i jump over enemy piece at (x1,y1) to empty location (x2,x2)
	private int canAttack(int [][] bs,int x1, int y1, int x2, int y2, int otherPlayer)
	{
		if(isValid(x1, y1) == 0 || isValid(x2, y2) == 0 )
			return 0;
		if(Utils.getOwner(bs[x1][y1]) == otherPlayer && bs[x2][y2] == BLANK)
			return 1;
		return 0;
	}

	//best solution found so far
	private int chosenMoveValue = -1;
	//solution found for current depth iteration
	private Move tempSolution;
	private int tempValue;

	//now many nodes were pruned in current depth iteration
	private int pruneCount = 0;
	private int depthCutOff = 0;
}


text:
//
//  BooksViewController.m
//  CRUDsy
//
//  Created by vlad gorbenko on 8/17/15.
//  Copyright (c) 2015 vlad gorbenko. All rights reserved.
//

#import "BooksViewController.h"

#import "Author.h"
#import "Book.h"

@interface BooksViewController ()

@property (nonatomic, strong) NSArray *books;

@end

@implementation BooksViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    if(self.author) {
        NSSortDescriptor *titleSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
        self.books = [[self.author.books allObjects] sortedArrayUsingDescriptors:@[titleSortDescriptor]];
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.books.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BookTableViewCell" forIndexPath:indexPath];
    Book *book = [self.books objectAtIndex:indexPath.row];
    cell.textLabel.text = book.title;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", book.price];
    return cell;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<title>SortObjectsAlongPolyline — armacode Documentation</title>
<link href="../../_static/basic.css" rel="stylesheet" type="text/css"/>
<link href="../../_static/pygments.css" rel="stylesheet" type="text/css"/>

<link href="../../_static/ar-ma_favicon.ico" rel="shortcut icon"/>
<link href="../../index.html" rel="top" title="armacode Documentation"/>
<link href="../../libraries.html" rel="up" title="Libraries"/>
<link href="SortSynchronous.html" rel="next" title="SortSynchronous"/>
<link href="SortObjectsAlongCurve.html" rel="prev" title="SortObjectsAlongCurve"/>

Navigation

index

next |

previous |

armacode Documentation »

Libraries »

SortObjectsAlongPolyline¶

SortObjectsAlongPolyline(objects, polyline, tag=True)¶

Undocumented

Previous topic

SortObjectsAlongCurve

Next topic

SortSynchronous

This Page

Show Source

Quick search

<form action="../../search.html" class="search" method="get">
<input name="q" type="text"/>
<input type="submit" value="Go"/>
<input name="check_keywords" type="hidden" value="yes"/>
<input name="area" type="hidden" value="default"/>
</form>

    Enter search terms or a module, class or function name.

Navigation

index

next |

previous |

armacode Documentation »

Libraries »

        © Copyright 2014, Tony Ho.
      Created using Sphinx 1.3.5.


text:
package io.vavr.concurrent;

import io.vavr.CheckedConsumer;
import io.vavr.CheckedFunction1;
import io.vavr.collection.Queue;
import io.vavr.control.Option;
import io.vavr.control.Try;

import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * INTERNAL API - This class is subject to change.
 *
 * @param <T> Result of the computation.
 * @author Daniel Dietrich
 */
// TODO: where to use UncaughtExceptionHandler?
final class FutureImpl<T> implements Future<T> {

    /**
     * Used to start new threads.
     */
    private final ExecutorService executorService;

    /**
     * Used to synchronize state changes.
     */
    private final Object lock = new Object();

    /**
     * Indicates if this Future is cancelled
     */
    @GuardedBy("lock")
    private volatile boolean cancelled;

    /**
     * Once the Future is completed, the value is defined.
     */
    @GuardedBy("lock")
    private volatile Option<Try<T>> value;

    /**
     * The queue of actions is filled when calling onComplete() before the Future is completed or cancelled.
     * Otherwise actions = null.
     */
    @GuardedBy("lock")
    private Queue<Consumer<Try<T>>> actions;

    /**
     * The queue of waiters is filled when calling await() before the Future is completed or cancelled.
     * Otherwise waiters = null.
     */
    @GuardedBy("lock")
    private Queue<Thread> waiters;

    /**
     * Once a computation is started via run(), job is defined and used to control the lifecycle of the computation.
     *

     * The {@code java.util.concurrent.Future} is not intended to store the result of the computation, it is stored in
     * {@code value} instead.
     */
    @GuardedBy("lock")
    private java.util.concurrent.Future<?> job;

    // single constructor
    private FutureImpl(ExecutorService executorService, Option<Try<T>> value, Queue<Consumer<Try<T>>> actions, Queue<Thread> waiters, CheckedFunction1<FutureImpl<T>, java.util.concurrent.Future<?>> jobFactory) {
        this.executorService = executorService;
        synchronized (lock) {
            this.cancelled = false;
            this.value = value;
            this.actions = actions;
            this.waiters = waiters;
            try {
                this.job = jobFactory.apply(this);
            } catch(Throwable x) {
                tryComplete(Try.failure(x));
            }
        }
    }

    /**
     * Creates a {@code FutureImpl} that is immediately completed with the given value. No task will be started.
     *
     * @param executorService An {@link ExecutorService} to run and control the computation and to perform the actions.
     * @param value the result of this Future
     */
    @SuppressWarnings("unchecked")
    static <T> FutureImpl<T> of(ExecutorService executorService, Try<? extends T> value) {
        return new FutureImpl<>(executorService, Option.some(Try.narrow(value)), null, null, ignored -> null);
    }

    /**
     * Creates a {@code FutureImpl} that is eventually completed.
     * The given {@code computation} is synchronously executed, no thread is started.
     *
     * @param executorService  An {@link ExecutorService} to run and control the computation and to perform the actions.
     * @param computation A non-blocking computation
     * @param <T> value type of the Future
     * @return a new {@code FutureImpl} instance
     */
    static <T> FutureImpl<T> sync(ExecutorService executorService, CheckedConsumer<Predicate<Try<? extends T>>> computation) {
        return new FutureImpl<>(executorService, Option.none(), Queue.empty(), Queue.empty(), future -> {
            computation.accept(future::tryComplete);
            return null;
        });
    }

    /**
     * Creates a {@code FutureImpl} that is eventually completed.
     * The given {@code computation} is asynchronously executed, a new thread is started.
     *
     * @param executorService  An {@link ExecutorService} to run and control the computation and to perform the actions.
     * @param computation A (possibly blocking) computation
     * @param <T> value type of the Future
     * @return a new {@code FutureImpl} instance
     */
    static <T> FutureImpl<T> async(ExecutorService executorService, CheckedConsumer<Predicate<Try<? extends T>>> computation) {
        // In a single-threaded context this Future may already have been completed during initialization.
        return new FutureImpl<>(executorService, Option.none(), Queue.empty(), Queue.empty(), future -> executorService.submit(() -> {
            try {
                computation.accept(future::tryComplete);
            } catch (Throwable x) {
                future.tryComplete(Try.failure(x));
            }
        }));
    }

    @Override
    public Future<T> await() {
        if (!isCompleted()) {
            _await(-1L, -1L, null);
        }
        return this;
    }

    @Override
    public Future<T> await(long timeout, TimeUnit unit) {
        final long now = System.nanoTime();
        Objects.requireNonNull(unit, "unit is null");
        if (timeout < 0) {
            throw new IllegalArgumentException("negative timeout");
        }
        if (!isCompleted()) {
            _await(now, timeout, unit);
        }
        return this;
    }

    /**
     * Blocks the current thread.
     *

     * If timeout = 0 then {@code LockSupport.park()} is called (start, timeout and unit are not used),
     * otherwise {@code LockSupport.park(timeout, unit}} is called.
     *

     * If a timeout > -1 is specified and the deadline is not met, this Future fails with a {@link TimeoutException}.
     *

     * If this Thread was interrupted, this Future fails with a {@link InterruptedException}.
     *
     * @param start the start time in nanos, based on {@linkplain System#nanoTime()}
     * @param timeout a timeout in the given {@code unit} of time
     * @param unit a time unit
     */
    private void _await(long start, long timeout, TimeUnit unit) {
        try {
            ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() {

                final long duration = (unit == null) ? -1 : unit.toNanos(timeout);
                final Thread thread = Thread.currentThread();

                boolean threadEnqueued = false;

                /**
                 * Parks the Future's thread.
                 *

                 * LockSupport.park() / parkNanos() may return when the Thread is permitted to be scheduled again.
                 * If so, the Future's tryComplete() method wasn't called yet. In that case the block() method is
                 * called again. The remaining timeout is recalculated accordingly.
                 *
                 * @return true, if this Future is completed, false otherwise
                 * @throws InterruptedException not thrown by us, we complete the Future directly in that case
                 */
                @Override
                public boolean block() throws InterruptedException {
                    try {
                        if (!threadEnqueued) {
                            synchronized (lock) {
                                waiters = waiters.enqueue(thread);
                            }
                            threadEnqueued = true;
                        }
                        if (timeout > -1) {
                            final long delta = System.nanoTime() - start;
                            final long remainder = duration - delta;
                            LockSupport.parkNanos(remainder); // returns immediately if remainder <= 0
                            if (System.nanoTime() - start > duration) {
                                tryComplete(Try.failure(new TimeoutException("timeout after " + timeout + " " + unit)));
                            }
                        } else {
                            LockSupport.park();
                        }
                        if (thread.isInterrupted()) {
                            tryComplete(Try.failure(new InterruptedException()));
                        }
                    } catch(Throwable x) {
                        tryComplete(Try.failure(x));
                    }
                    return isCompleted();
                }
                @Override
                public boolean isReleasable() {
                    return isCompleted();
                }
            });
        } catch (Throwable x) {
            tryComplete(Try.failure(x));
        }
    }

    @Override
    public Future<T> cancel(boolean mayInterruptIfRunning) {
        if (!isCompleted()) {
            synchronized (lock) {
                Try.of(() -> job == null || job.cancel(mayInterruptIfRunning))
                        .recover(ignored -> job != null && job.isCancelled())
                        .onSuccess(cancelled -> {
                            if (cancelled) {
                                this.cancelled = tryComplete(Try.failure(new CancellationException()));
                            }
                        });
            }
        }
        return this;
    }

    @Override
    public ExecutorService executorService() {
        return executorService;
    }

    @Override
    public Option<Try<T>> getValue() {
        return value;
    }

    @Override
    public boolean isCancelled() {
        return cancelled;
    }

    @Override
    public boolean isCompleted() {
        return value.isDefined();
    }

    @SuppressWarnings("unchecked")
    @Override
    public Future<T> onComplete(Consumer<? super Try<T>> action) {
        Objects.requireNonNull(action, "action is null");
        if (isCompleted()) {
            perform(action);
        } else {
            synchronized (lock) {
                if (isCompleted()) {
                    perform(action);
                } else {
                    actions = actions.enqueue((Consumer<Try<T>>) action);
                }
            }
        }
        return this;
    }

    // This class is MUTABLE and therefore CANNOT CHANGE DEFAULT equals() and hashCode() behavior.
    // See http://stackoverflow.com/questions/4718009/mutable-objects-and-hashcode

    @Override
    public String toString() {
        final Option<Try<T>> value = this.value;
        final String s = (value == null || value.isEmpty()) ? "?" : value.get().toString();
        return stringPrefix() + "(" + s + ")";
    }

    /**
     * INTERNAL METHOD, SHOULD BE USED BY THE CONSTRUCTOR, ONLY.
     *

     * Completes this Future with a value and performs all actions.
     *

     * This method is idempotent. I.e. it does nothing, if this Future is already completed.
     *
     * @param value A Success containing a result or a Failure containing an Exception.
     * @throws IllegalStateException if the Future is already completed or cancelled.
     * @throws NullPointerException  if the given {@code value} is null.
     */
    private boolean tryComplete(Try<? extends T> value) {
        Objects.requireNonNull(value, "value is null");
        if (isCompleted()) {
            return false;
        } else {
            final Queue<Consumer<Try<T>>> actions;
            final Queue<Thread> waiters;
            // it is essential to make the completed state public *before* performing the actions
            synchronized (lock) {
                if (isCompleted()) {
                    actions = null;
                    waiters = null;
                } else {
                    // the job isn't set to null, see isCancelled()
                    actions = this.actions;
                    waiters = this.waiters;
                    this.value = Option.some(Try.narrow(value));
                    this.actions = null;
                    this.waiters = null;
                    this.job = null;
                }
            }
            if (waiters != null) {
                waiters.forEach(this::unlock);
            }
            if (actions != null) {
                actions.forEach(this::perform);
                return true;
            } else {
                return false;
            }
        }
    }

    private void perform(Consumer<? super Try<T>> action) {
        try {
            executorService.execute(() -> action.accept(value.get()));
        } catch(Throwable x) {
            // ignored // TODO: tell UncaughtExceptionHandler?
        }
    }

    private void unlock(Thread waiter) {
        try {
            LockSupport.unpark(waiter);
        } catch(Throwable x) {
            // ignored // TODO: tell UncaughtExceptionHandler?
        }
    }
}


text:
namespace WebApiStrap.Domain
{
    public enum ModelExceptionReasons
    {
        NotFound
    }
}


text:
module.exports = function (config, app) {

	var path = require('path');
	var routey = require('routey');

	routey({
	    routeConfigPath: path.join(__dirname, "rest"),
	    verbose: true,
	    handlerParams: {
	    	host: config.host,
	    	port: config.port,
	    	logger: config.logger,
	    },
	    parentRoute: config.parentRoute,

	}, app);
};


text:
/**
 * Draws a quadratic Bezier line (http://en.wikipedia.org/wiki/B%C3%A9zier_curve) going from "from" to "to",
 * according to the options given. Available options are:
 *   - color, opacity and weight: Same as for GPolyline.
 *   - steps: Number of steps taken between "from" and "to" along the Bezier line. The GPolyline will contain steps + 1 vertices.
 *   - controlPoint: The control point for the quadratic Bezier line. If not given, one will be calculated, using the curveFactor.
 *   - curveFactor: The calculateed control point is equal to the middle-point between "from" and "to", with an offset. A curveFactor
 *     of 0.5 makes the distance from the control point to the line between "from" and "to" be half the distance between "from" and "to".
 *
 * Notes: Please be advised that this current version actually draws the line on the surface of the planet, which means that lines
 *        will be more and more distorted the closer to the poles they are drawn.
 *
 *        Methods in this class are only needed by the class itself. Users need only call the constructor with the right options.
 *        If a change on a line is needed, a user should create another one and not modify the old one.
 *        Also, the mergeOptions function is only used inside the constructor, but it didn't seem to make sense to make it a method.
 *
 * Usage:
 *   var curve = new QuadraticBezierLine(from, to, {options});
 *   map.addOverlay(curve);
 *
 * @param {GLatLng} from
 * @param {GLatLng} to
 * @param {Object} opts
 *
 * @author Marcelo Alvim
 *
 * Code licensed under the WTFPL version 2. For more details see the COPYING file.
 */
var QuadraticBezierLine = function(from, to, opts) {
	this.from = from;
	this.to = to;
	this.opts = QuadraticBezierLine.mergeOptions(opts, QuadraticBezierLine.defaults);
	this.control = this.opts.controlPoint || this.calculateControlPoint();
	this.points = null;
	GPolyline.call(this, this.getPolylinePoints(), this.opts.color, this.opts.weight, this.opts.opacity);
};

QuadraticBezierLine.prototype = new GPolyline();
QuadraticBezierLine.defaults = {color: "#ff0000", opacity: 0.6, weight: 5, steps: 20, controlPoint: null, curveFactor: 0.4};

/**
 * Gets the array of points that will be used to construct the GPolyline object.
 *
 * @param {GLatLng} from
 * @param {GLatLng} to
 * @param {Object} opts
 *
 * @return Array<GLatLng>
 */
QuadraticBezierLine.prototype.getPolylinePoints = function() {
	var self = this;

	return this.points || (function() {
		self.points = [];
		var steps = (self.opts.steps % 2 === 0) ? (self.opts.steps) : (self.opts.steps + 1); // number of steps has to be even
		var pt = null;
		for(var t = 0; t <= steps; t++) {
			pt = self.getPoint(t * (1 / steps));
			if(t === (steps / 2)) {
				self.middlePoint = pt;
			}
			self.points.push(pt);
		}
		return self.points;
	})();
};

/**
 * Calculates the control point using the two endpoints and the "curve factor".
 * Does that by calculating the middle point, then offseting it away from the line that connects the two endpoints.
 * The amount of offseting is given by the factor. A factor of 1.0 makes the distance from the point to the line be
 * equal to the length of the line. 0.5 makes it half the line length.
 *
 * @param {GLatLng} from
 * @param {GLatLng} to
 * @param {float} factor
 *
 * @return GLatLng
 */
QuadraticBezierLine.prototype.calculateControlPoint = function() {
	var factor = this.opts.curveFactor;
	var middlePoint = {lat: (this.from.lat() + this.to.lat()) / 2.0, lng: (this.from.lng() + this.to.lng()) / 2.0};
	return new GLatLng((middlePoint.lng - this.to.lng()) * factor + middlePoint.lat, (this.to.lat() - middlePoint.lat) * factor + middlePoint.lng);
};

/**
 * Calculates a point in the Bezier line, based on the two endpoints, the control point, and the "t" parameter,
 * which will be between 0 and 1 according to the number of steps.
 *
 * @param {GLatLng} from
 * @param {GLatLng} control
 * @param {GLatLng} to
 * @param {float} t
 *
 * @return GLatLng
 */
QuadraticBezierLine.prototype.getPoint = function(t) {
	var lat = this.bezier(t, function(pt) {return pt.lat();});
	var lng = this.bezier(t, function(pt) {return pt.lng();});
	return new GLatLng(lat, lng);
};

/**
 * The actual Quadratic Bezier function. Calculates a number based on the three points and the "t" parameter.
 *
 * @param {float} t, the current interpolation step
 * @param {function} getValue, a function that will be called with this.from, this.control and this.to, and will
 *   return the value (lat or lng) that will be used to calculate the current point
 *
 * @return float, the calculated bezier value
 */
QuadraticBezierLine.prototype.bezier = function(t, getValue) {
	return (((1 - t) * (1 - t)) * (getValue(this.from))) + ((2 * t) * (1 - t) * (getValue(this.control))) + ((t * t) * (getValue(this.to)));
};

/**
 * Merges opts into defaults. This is similar to 'extend' functions in frameworks such as jQuery and Prototype. It's just
 * here in order to make this library framework agnostic.
 */
QuadraticBezierLine.mergeOptions = function(opts, defaults) {
	var o = {};
	if(!opts) {
		return defaults;
	} else {
		o = {};
		for(var attr in defaults) {
			if(defaults.hasOwnProperty(attr)) {
				o[attr] = opts[attr] || defaults[attr];
			}
		}
		return o;
	}
};


text:
@interface NSDate(Format)
- (NSString *)getWeekDayString:(NSInteger)iDay;
- (BOOL)isSameDay:(NSDate*)date;
- (BOOL)isYestoday;
- (BOOL)isBeforeYestoday;
- (BOOL)isInWeek;
- (BOOL)isInMonth;
- (BOOL)isInYear;

- (NSDateComponents*)getComponentOfDate;
- (NSString *)getConversationTimeString;
- (NSString*)formatSectionTime;
@end


text:
<?php

namespace Teknasyon\Stage\Notification;

use PHPUnit\Framework\TestCase;
use Teknasyon\Stage\Job\Job;

class JobCompletedNotificationTest extends TestCase
{
    public function testParameters()
    {
        $job = $this->getMockBuilder(Job::class)->getMock();
        $notification = new JobCompletedNotification($job);
        $this->assertEquals($job, $notification->getJob());
    }
}


text:
import os, sys

try:
    import httpmessage
except ImportError:
    from os.path import split, dirname, abspath
    parent_dir = split(dirname(abspath(__file__)))[0]
    sys.path.append(parent_dir)

import httpmessage


text:
{
  if (!fiber) {
    return [];
  }

  var currentParent = ReactFiberTreeReflection.findCurrentFiberUsingSlowPath(
    fiber
  );

  if (!currentParent) {
    return [];
  }

  let node = currentParent;
  let ret = [];

  while (true) {
    if (
      node.tag === HostComponent ||
      node.tag === HostText ||
      node.tag === ClassComponent ||
      node.tag === FunctionalComponent
    ) {
      var publicInst = node.stateNode;

      if (test(publicInst)) {
        ret.push(publicInst);
      }
    }

    if (node.child) {
      node.child.return = node;
      node = node.child;
      continue;
    }

    if (node === currentParent) {
      return ret;
    }

    while (!node.sibling) {
      if (!node.return || node.return === currentParent) {
        return ret;
      }

      node = node.return;
    }

    node.sibling.return = node.return;
    node = node.sibling;
  }
}


text:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="25dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="25dp" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:id="@+id/main_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <TextView
                    style="@style/DemoMainActivity_Button_Title_Style"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:text="@string/app_main_login"/>

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:orientation="horizontal" >

                    <ImageView
                        android:id="@+id/user_logo"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:visibility="gone" />

                    <TextView
                        android:id="@+id/user_nickname"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:gravity="bottom"
                        android:textColor="#80505050"
                        android:textSize="18sp"
                        android:visibility="gone" />
                </LinearLayout>
            </RelativeLayout>

            <Button
                android:id="@+id/new_login_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <Button
                android:id="@+id/server_side_login_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <TextView
                style="@style/DemoMainActivity_Button_Title_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dip"
                android:text="@string/app_main_api" />

            <Button
                android:id="@+id/main_qqShare_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_qq_share" />

            <Button
                android:id="@+id/qqShare_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="QQ分享" />

            <Button
                android:id="@+id/main_qzoneShare_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_qzon_share" />

            <!--<Button
                android:id="@+id/main_social_api_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_social_api"/>-->

            <Button
                android:id="@+id/main_sso_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_is_support_sso_login" />

            <Button
                android:id="@+id/main_getInfo_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_get_user_info" />

            <!-- 下面的注释请勿删除,编译lite版的时候需要删除[liteexludestart] [liteexludeend]区间的代码 -->
            <!--[liteexludestart]-->
            <Button
                android:id="@+id/game_add_friend"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_add_friend_in_game" />
            <Button
                android:id="@+id/main_avatar_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_set_avatar" />

            <!--<Button
                android:id="@+id/main_qzonePic_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_visit_qzone_gallery" />-->

            <Button
                android:id="@+id/main_tqqInfo_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_get_weibo_info" />

            <Button
                android:id="@+id/main_wap_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_wap" />

            <Button
                android:id="@+id/main_appbar_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_appbar" />

            <Button
                android:id="@+id/main_others_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_others" />

            <Button
                android:id="@+id/main_qqgroup_btn"
                style="@style/DemoMainActivity_Button_Style"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/app_main_qqgroupp_api" />
            <!--[liteexludeend]-->
        </LinearLayout>
    </ScrollView>

</LinearLayout>


text:
<?php

namespace Bazinga\Bundle\GeocoderBundle\Mapping;

/**
 * @author Markus Bachmann <markus.bachmann@bachi.biz>
 */
class ClassMetadata
{
    /**
     * @var \ReflectionProperty
     */
    public $addressProperty;

    /**
     * @var \ReflectionProperty
     */
    public $latitudeProperty;

    /**
     * @var \ReflectionProperty
     */
    public $longitudeProperty;
}