<commit_before>import core from 'core-js';
import {History} from 'aurelia-history';

// Cached regex for stripping a leading hash/slash and trailing space.
var routeStripper = /^#?\/*|\s+$/g;

// Cached regex for stripping leading and trailing slashes.
var rootStripper = /^\/+|\/+$/g;

// Cached regex for detecting MSIE.
var isExplorer = /msie [\w.]+/;

// Cached regex for removing a trailing slash.
var trailingSlash = /\/$/;

// Cached regex for detecting if a URL is absolute,
// i.e., starts with a scheme or is scheme-relative.
// See http://www.ietf.org/rfc/rfc2396.txt section 3.1 for valid scheme format
const absoluteUrl = /^([a-z][a-z0-9+\-.]*:)?\/\//i;

// Update the hash location, either replacing the current entry, or adding
// a new one to the browser history.
function updateHash(location, fragment, replace) {
  if (replace) {
    var href = location.href.replace(/(javascript:|#).*$/, '');
    location.replace(href + '#' + fragment);
  } else {
    // Some browsers require that `hash` contains a leading #.
    location.hash = '#' + fragment;
  }
}

export class BrowserHistory extends History {
  constructor(){
    super();

    this.interval = 50;
    this.active = false;
    this.previousFragment = '';
    this._checkUrlCallback = this.checkUrl.bind(this);

    if (typeof window !== 'undefined') {
      this.location = window.location;
      this.history = window.history;
    }
  }

  getHash(window?:Window):string {
    var match = (window || this).location.href.match(/#(.*)$/);
    return match ? match[1] : '';
  }

  getFragment(fragment:string, forcePushState?:boolean):string {
    var root;

    if (!fragment) {
      if (this._hasPushState || !this._wantsHashChange || forcePushState) {
        fragment = this.location.pathname + this.location.search;
        root = this.root.replace(trailingSlash, '');
        if (!fragment.indexOf(root)) {
          fragment = fragment.substr(root.length);
        }
      } else {
        fragment = this.getHash();
      }
    }

    return '/' + fragment.replace(routeStripper, '');
  }

  activate(options?:Object):boolean {
    if (this.active) {
      throw new Error("History has already been activated.");
    }

    this.active = true;

    // Figure out the initial configuration. Do we need an iframe?
    // Is pushState desired ... is it available?
    this.options = Object.assign({}, { root: '/' }, this.options, options);
    this.root = this.options.root;
    this._wantsHashChange = this.options.hashChange !== false;
    this._wantsPushState = !!this.options.pushState;
    this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);

    var fragment = this.getFragment();

    // Normalize root to always include a leading and trailing slash.
    this.root = ('/' + this.root + '/').replace(rootStripper, '/');
<commit_msg>fix(history): fixed regression issue which added double slashes to the pushState fragment<commit_after>import core from 'core-js';
import {History} from 'aurelia-history';

// Cached regex for stripping a leading hash/slash and trailing space.
var routeStripper = /^#?\/*|\s+$/g;

// Cached regex for stripping leading and trailing slashes.
var rootStripper = /^\/+|\/+$/g;

// Cached regex for detecting MSIE.
var isExplorer = /msie [\w.]+/;

// Cached regex for removing a trailing slash.
var trailingSlash = /\/$/;

// Cached regex for detecting if a URL is absolute,
// i.e., starts with a scheme or is scheme-relative.
// See http://www.ietf.org/rfc/rfc2396.txt section 3.1 for valid scheme format
const absoluteUrl = /^([a-z][a-z0-9+\-.]*:)?\/\//i;

// Update the hash location, either replacing the current entry, or adding
// a new one to the browser history.
function updateHash(location, fragment, replace) {
  if (replace) {
    var href = location.href.replace(/(javascript:|#).*$/, '');
    location.replace(href + '#' + fragment);
  } else {
    // Some browsers require that `hash` contains a leading #.
    location.hash = '#' + fragment;
  }
}

export class BrowserHistory extends History {
  constructor(){
    super();

    this.interval = 50;
    this.active = false;
    this.previousFragment = '';
    this._checkUrlCallback = this.checkUrl.bind(this);

    if (typeof window !== 'undefined') {
      this.location = window.location;
      this.history = window.history;
    }
  }

  getHash(window?:Window):string {
    var match = (window || this).location.href.match(/#(.*)$/);
    return match ? match[1] : '';
  }

  getFragment(fragment:string, forcePushState?:boolean):string {
    var root;

    if (!fragment) {
      if (this._hasPushState || !this._wantsHashChange || forcePushState) {
        fragment = this.location.pathname + this.location.search;
        root = this.root.replace(trailingSlash, '');
        if (!fragment.indexOf(root)) {
          fragment = fragment.substr(root.length);
        }
      } else {
        fragment = this.getHash();
      }
    }
    
    // If fragment is already prefixed with a slash, don't add another
    if (fragment.charAt(0) === '/') {
      return fragment.replace(routeStripper, '');
    }

    return '/' + fragment.replace(routeStripper, '');
  }

  activate(options?:Object):boolean {
    if (this.active) {
      throw new Error("History has already been activated.");
    }

    this.active = true;

    // Figure out the initial configuration. Do we need an iframe?
    // Is pushState desired ... is it available?
    this.options = Object.assign({}, { root: '/' }, this.options, options);
    this.root = this.options.root;
    this._wantsHashChange = this.options.hashChange !== false;
    this._wantsPushState = !!this.options.pushState;
    this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);

    var fragment = this.getFragment();

    // Normalize root to always include a leading and trailing slash.
    this.root = ('/' + this.root + '/').replace(rootStripper, '/');

{'fraction_non_alphanumeric': 0.15145924186514592, 'fraction_numerical': 0.0038577658503857765, 'mean_word_length': 2.9673985362608115, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '6383914', 'n_tokens_mistral': 1840, 'n_tokens_neox': 1783, 'n_words': 490}