<commit_before>import Crumb from './config/Crumb';
import State from './config/State';
import StateContext from './StateContext';
import StateHandler from './StateHandler';

interface FluentNavigator {
    url: string,
    navigate(stateKey: string, navigationData?: any): FluentNavigator;
    refresh(navigationData?: any): FluentNavigator;
}

function createFluentNavigator(states: { [index: string]: State }, stateHandler: StateHandler, stateContext = new StateContext()): FluentNavigator {
    function getFluentContext(state: State, data: any, url: string): StateContext {
        var fluentContext = new StateContext();
        fluentContext.state = state;
        fluentContext.url = url;
        fluentContext.crumbs = data[state.crumbTrailKey];
        delete data[state.crumbTrailKey];
        fluentContext.data = data;
        fluentContext.nextCrumb = new Crumb(data, state, url, stateHandler.getLink(state, data), false);
        return fluentContext;
    }

    function navigateLink(url): FluentNavigator {
        var { state, data } = stateHandler.parseLink(url);
        return createFluentNavigator(states, stateHandler, getFluentContext(state, data, url));
    }

    return {
        url: stateContext.url,
        navigate: function(stateKey: string, navigationData?: any): FluentNavigator {
            if (!states[stateKey])
                throw new Error(stateKey + ' is not a valid State');
            if (typeof navigationData === 'function')
                navigationData = navigationData(stateContext.data);
            var url = stateHandler.getLink(states[stateKey], navigationData, stateContext.crumbs, stateContext.nextCrumb);
            return navigateLink(url);
        },
        refresh: function(navigationData?: any): FluentNavigator {
            if (typeof navigationData === 'function')
                navigationData = navigationData(stateContext.data);
            var url = stateHandler.getLink(stateContext.state, navigationData, stateContext.crumbs, stateContext.nextCrumb);
            if (url == null)
                throw new Error('Invalid route data, a mandatory route parameter has not been supplied a value');
            return navigateLink(url);
        }
    }
}
export { FluentNavigator, createFluentNavigator };<commit_msg>Added navigate back to fluent navigator<commit_after>import Crumb from './config/Crumb';
import State from './config/State';
import StateContext from './StateContext';
import StateHandler from './StateHandler';

interface FluentNavigator {
    url: string,
    navigate(stateKey: string, navigationData?: any): FluentNavigator;
    refresh(navigationData?: any): FluentNavigator;
    navigateBack(distance: number): FluentNavigator;
}

function createFluentNavigator(states: { [index: string]: State }, stateHandler: StateHandler, stateContext = new StateContext()): FluentNavigator {
    function getFluentContext(state: State, data: any, url: string): StateContext {
        var fluentContext = new StateContext();
        fluentContext.state = state;
        fluentContext.url = url;
        fluentContext.crumbs = data[state.crumbTrailKey];
        delete data[state.crumbTrailKey];
        fluentContext.data = data;
        fluentContext.nextCrumb = new Crumb(data, state, url, stateHandler.getLink(state, data), false);
        return fluentContext;
    }

    function navigateLink(url): FluentNavigator {
        var { state, data } = stateHandler.parseLink(url);
        return createFluentNavigator(states, stateHandler, getFluentContext(state, data, url));
    }

    return {
        url: stateContext.url,
        navigate: function(stateKey: string, navigationData?: any): FluentNavigator {
            if (!states[stateKey])
                throw new Error(stateKey + ' is not a valid State');
            if (typeof navigationData === 'function')
                navigationData = navigationData(stateContext.data);
            var url = stateHandler.getLink(states[stateKey], navigationData, stateContext.crumbs, stateContext.nextCrumb);
            return navigateLink(url);
        },
        refresh: function(navigationData?: any): FluentNavigator {
            if (typeof navigationData === 'function')
                navigationData = navigationData(stateContext.data);
            var url = stateHandler.getLink(stateContext.state, navigationData, stateContext.crumbs, stateContext.nextCrumb);
            if (url == null)
                throw new Error('Invalid route data, a mandatory route parameter has not been supplied a value');
            return navigateLink(url);
        },
        navigateBack: function(distance: number): FluentNavigator {
            if (!(distance <= stateContext.crumbs.length && distance > 0))
                throw new Error('The distance parameter must be greater than zero and less than or equal to the number of Crumbs (' + this.stateContext.crumbs.length + ')');
            var url = stateContext.crumbs[stateContext.crumbs.length - distance].url;
            return navigateLink(url);
        }
    }
}
export { FluentNavigator, createFluentNavigator };
{'fraction_non_alphanumeric': 0.10084198159389074, 'fraction_numerical': 0.00019580967299784609, 'mean_word_length': 3.1868852459016392, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, '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': '2955096', 'n_tokens_mistral': 1313, 'n_tokens_neox': 1315, 'n_words': 356}