<commit_before>/**
 * TopLevelState service for managing top level state.
 *
 * This service is used to interact with the general state of the
 * application.  It also takes care of reflecting this state in the
 * URI by the means of areas.
 *
 * An area consists of a routing function (which translates URI to
 * state), a reverse routing function (which translates state to URI),
 * and a template.
 *
 * The application can interact with this service via the functions
 * get(), set(), and on().
 *
 * This service very much resembles ngRoute, especially in the way
 * the areas are configured.  It differs from ngRoute in that it can
 * change paths without a reload and in being more flexibel.
 */

import _ = require("lodash");

import AdhConfig = require("../Config/Config");
import AdhEventHandler = require("../EventHandler/EventHandler");

var pkgLocation = "/TopLevelState";


export interface IAreaInput {
    route? : (path : string, search : {[key : string] : string}) => ng.IPromise<{[key : string] : string}>;
    reverse? : (data : {[key : string] : string}) => {
        path : string;
        search : {[key : string] : string};
    };
    template? : string;
    templateUrl? : string;
}


export interface IArea {
    prefix : string;
    route : (path : string, search : {[key : string] : string}) => ng.IPromise<{[key : string] : string}>;
    reverse : (data : {[key : string] : string}) => {
        path : string;
        search : {[key : string] : string};
    };
    template : string;
}


export class Provider {
    public areas : {[key : string]: any};
    public default : any;
    public $get;

    constructor() {
        var self = this;

        this.areas = {};
        this.default = () => {
            return {
                template: "<h1>404 Not Found</h1>"
            };
        };

        this.$get = ["adhEventHandlerClass", "$location", "$rootScope", "$http", "$q", "$templateCache", "$injector",
            (adhEventHandlerClass, $location, $rootScope, $http, $q, $templateCache, $injector) => {
                return new Service(self, adhEventHandlerClass, $location, $rootScope, $http, $q, $templateCache, $injector);
            }];
    }

    public when(prefix : string, factory : (...args : any[]) => IAreaInput);
    public when(prefix : string, factory : any[]);
    public when(prefix, factory) {
        this.areas[prefix] = factory;
        return this;
    }

    public otherwise(factory : (...args : any[]) => IAreaInput);
    public otherwise(factory : any[]);
    public otherwise(factory) {
        this.default = factory;
        return this;
    }
}


export class Service {
    private eventHandler : AdhEventHandler.EventHandler;
    private area : IArea;
    private blockTemplate : boolean;

    // NOTE: data and on could be replaced by a scope and $watch, respectively.
    private data : {[key : string] : string};

    constructor(
        private provider : Provider,
        adhEventHandlerClass : typeof AdhEventHandler.EventHandler,
        private $location : ng.ILocationService,
        private $rootScope : ng.IScope,
        private $http : ng.IHttpService,
        private $q : ng.IQService,
        private $templateCache : ng.ITemplateCacheService,
        private $injector : ng.auto.IInjectorService
    ) {
        var self : Service = this;

        this.eventHandler = new adhEventHandlerClass();
        this.data = {};

        this.$rootScope.$watch(() => self.$location.absUrl(), () => {
            self.fromLocation();
        });
    }

    private templateRequest(url) : ng.IPromise<string> {
        // FIXME: in future versions of angular, this should be replaced by $templateRequest
        var template = this.$templateCache.get(url);

        if (typeof template === "undefined") {
            return this.$http.get(url).then((response) => {
                var template = response.data;
                this.$templateCache.put(url, template);
                return template;
            });
        } else {
            return this.$q.when(template);
        }
    }

    private getArea() : IArea {
        var self = this;

        var defaultRoute = (path, search) => {
            var data = _.clone(search);
            data["_path"] = path;
            return self.$q.when(data);
        };

        var defaultReverse = (data) => {
            var ret = {
                path: data["_path"],
                search: _.clone(data)
            };
            delete ret.search["_path"];
            return ret;
        };

        var prefix : string = this.$location.path().split("/")[1];

        if (typeof this.area === "undefined" || prefix !== this.area.prefix) {
            this.blockTemplate = true;
            var fn = this.provider.areas.hasOwnProperty(prefix) ? this.provider.areas[prefix] : this.provider.default;
            var areaInput : IAreaInput = this.$injector.invoke(fn);
            var area : IArea = {
                prefix: prefix,
                route: typeof areaInput.route !== "undefined" ? areaInput.route : defaultRoute,
                reverse: typeof areaInput.reverse !== "undefined" ? areaInput.reverse : defaultReverse,
                template: ""
            };<commit_msg>bind route/reverse to areaInput object<commit_after>/**
 * TopLevelState service for managing top level state.
 *
 * This service is used to interact with the general state of the
 * application.  It also takes care of reflecting this state in the
 * URI by the means of areas.
 *
 * An area consists of a routing function (which translates URI to
 * state), a reverse routing function (which translates state to URI),
 * and a template.
 *
 * The application can interact with this service via the functions
 * get(), set(), and on().
 *
 * This service very much resembles ngRoute, especially in the way
 * the areas are configured.  It differs from ngRoute in that it can
 * change paths without a reload and in being more flexibel.
 */

import _ = require("lodash");

import AdhConfig = require("../Config/Config");
import AdhEventHandler = require("../EventHandler/EventHandler");

var pkgLocation = "/TopLevelState";


export interface IAreaInput {
    route? : (path : string, search : {[key : string] : string}) => ng.IPromise<{[key : string] : string}>;
    reverse? : (data : {[key : string] : string}) => {
        path : string;
        search : {[key : string] : string};
    };
    template? : string;
    templateUrl? : string;
}


export interface IArea {
    prefix : string;
    route : (path : string, search : {[key : string] : string}) => ng.IPromise<{[key : string] : string}>;
    reverse : (data : {[key : string] : string}) => {
        path : string;
        search : {[key : string] : string};
    };
    template : string;
}


export class Provider {
    public areas : {[key : string]: any};
    public default : any;
    public $get;

    constructor() {
        var self = this;

        this.areas = {};
        this.default = () => {
            return {
                template: "<h1>404 Not Found</h1>"
            };
        };

        this.$get = ["adhEventHandlerClass", "$location", "$rootScope", "$http", "$q", "$templateCache", "$injector",
            (adhEventHandlerClass, $location, $rootScope, $http, $q, $templateCache, $injector) => {
                return new Service(self, adhEventHandlerClass, $location, $rootScope, $http, $q, $templateCache, $injector);
            }];
    }

    public when(prefix : string, factory : (...args : any[]) => IAreaInput);
    public when(prefix : string, factory : any[]);
    public when(prefix, factory) {
        this.areas[prefix] = factory;
        return this;
    }

    public otherwise(factory : (...args : any[]) => IAreaInput);
    public otherwise(factory : any[]);
    public otherwise(factory) {
        this.default = factory;
        return this;
    }
}


export class Service {
    private eventHandler : AdhEventHandler.EventHandler;
    private area : IArea;
    private blockTemplate : boolean;

    // NOTE: data and on could be replaced by a scope and $watch, respectively.
    private data : {[key : string] : string};

    constructor(
        private provider : Provider,
        adhEventHandlerClass : typeof AdhEventHandler.EventHandler,
        private $location : ng.ILocationService,
        private $rootScope : ng.IScope,
        private $http : ng.IHttpService,
        private $q : ng.IQService,
        private $templateCache : ng.ITemplateCacheService,
        private $injector : ng.auto.IInjectorService
    ) {
        var self : Service = this;

        this.eventHandler = new adhEventHandlerClass();
        this.data = {};

        this.$rootScope.$watch(() => self.$location.absUrl(), () => {
            self.fromLocation();
        });
    }

    private templateRequest(url) : ng.IPromise<string> {
        // FIXME: in future versions of angular, this should be replaced by $templateRequest
        var template = this.$templateCache.get(url);

        if (typeof template === "undefined") {
            return this.$http.get(url).then((response) => {
                var template = response.data;
                this.$templateCache.put(url, template);
                return template;
            });
        } else {
            return this.$q.when(template);
        }
    }

    private getArea() : IArea {
        var self = this;

        var defaultRoute = (path, search) => {
            var data = _.clone(search);
            data["_path"] = path;
            return self.$q.when(data);
        };

        var defaultReverse = (data) => {
            var ret = {
                path: data["_path"],
                search: _.clone(data)
            };
            delete ret.search["_path"];
            return ret;
        };

        var prefix : string = this.$location.path().split("/")[1];

        if (typeof this.area === "undefined" || prefix !== this.area.prefix) {
            this.blockTemplate = true;
            var fn = this.provider.areas.hasOwnProperty(prefix) ? this.provider.areas[prefix] : this.provider.default;
            var areaInput : IAreaInput = this.$injector.invoke(fn);
            var area : IArea = {
                prefix: prefix,
                route: typeof areaInput.route !== "undefined" ? areaInput.route.bind(areaInput) : defaultRoute,
                reverse: typeof areaInput.reverse !== "undefined" ? areaInput.reverse.bind(areaInput) : defaultReverse,
                template: ""
            };
{'fraction_non_alphanumeric': 0.12893111638954868, 'fraction_numerical': 0.0011401425178147269, 'mean_word_length': 2.2750466708151835, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3114762', 'n_tokens_mistral': 2892, 'n_tokens_neox': 2821, 'n_words': 854}