text: import { addFormatToken } from "../format/format";
  import { addUnitAlias } from "./aliases";
  import { addUnitPriority } from "./priorities";
  import {
  	addRegexToken,
  	match1to2,
  	matchWord,
  	regexEscape,
  } from "../parse/regex";
  import { addWeekParseToken } from "../parse/token";
  import toInt from "../utils/to-int";
  import isArray from "../utils/is-array";
  import indexOf from "../utils/index-of";
  import hasOwnProp from "../utils/has-own-prop";
  import { createUTC } from "../create/utc";
  import getParsingFlags from "../create/parsing-flags";
  
  // FORMATTING
  
  addFormatToken("d", 0, "do", "day");
  
  addFormatToken("dd", 0, 0, function (format) {
  	return this.localeData().weekdaysMin(this, format);
  });
  
  addFormatToken("ddd", 0, 0, function (format) {
  	return this.localeData().weekdaysShort(this, format);
  });
  
  addFormatToken("dddd", 0, 0, function (format) {
  	return this.localeData().weekdays(this, format);
  });
  
  addFormatToken("e", 0, 0, "weekday");
  addFormatToken("E", 0, 0, "isoWeekday");
  
  // ALIASES
  
  addUnitAlias("day", "d");
  addUnitAlias("weekday", "e");
  addUnitAlias("isoWeekday", "E");
  
  // PRIORITY
  addUnitPriority("day", 11);
  addUnitPriority("weekday", 11);
  addUnitPriority("isoWeekday", 11);
  
  // PARSING
  
  addRegexToken("d", match1to2);
  addRegexToken("e", match1to2);
  addRegexToken("E", match1to2);
  addRegexToken("dd", function (isStrict, locale) {
  	return locale.weekdaysMinRegex(isStrict);
  });
  addRegexToken("ddd", function (isStrict, locale) {
  	return locale.weekdaysShortRegex(isStrict);
  });
  addRegexToken("dddd", function (isStrict, locale) {
  	return locale.weekdaysRegex(isStrict);
  });
  
  addWeekParseToken(["dd", "ddd", "dddd"], function (input, week, config, token) {
  	var weekday = config._locale.weekdaysParse(input, token, config._strict);
  	// if we didn't get a weekday name, mark the date as invalid
  	if (weekday != null) {
  		week.d = weekday;
  	} else {
  		getParsingFlags(config).invalidWeekday = input;
  	}
  });
  
  addWeekParseToken(["d", "e", "E"], function (input, week, config, token) {
  	week[token] = toInt(input);
  });
  
  // HELPERS
  
  function parseWeekday(input, locale) {
  	if (typeof input !== "string") {
  		return input;
  	}
  
  	if (!isNaN(input)) {
  		return parseInt(input, 10);
  	}
  
  	input = locale.weekdaysParse(input);
  	if (typeof input === "number") {
  		return input;
  	}
  
  	return null;
  }
  
  function parseIsoWeekday(input, locale) {
  	if (typeof input === "string") {
  		return locale.weekdaysParse(input) % 7 || 7;
  	}
  	return isNaN(input) ? null : input;
  }
  
  // LOCALES
  function shiftWeekdays(ws, n) {
  	return ws.slice(n, 7).concat(ws.slice(0, n));
  }
  
  export var defaultLocaleWeekdays = "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split(
  	"_"
  );
  export function localeWeekdays(m, format) {
  	var weekdays = isArray(this._weekdays)
  		? this._weekdays
  		: this._weekdays[
  				m && m !== true && this._weekdays.isFormat.test(format)
  					? "format"
  					: "standalone"
  		  ];
  	return m === true
  		? shiftWeekdays(weekdays, this._week.dow)
  		: m
  		? weekdays[m.day()]
  		: weekdays;
  }
  
  export var defaultLocaleWeekdaysShort = "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split(
  	"_"
  );
  export function localeWeekdaysShort(m) {
  	return m === true
  		? shiftWeekdays(this._weekdaysShort, this._week.dow)
  		: m
  		? this._weekdaysShort[m.day()]
  		: this._weekdaysShort;
  }
  
  export var defaultLocaleWeekdaysMin = "Su_Mo_Tu_We_Th_Fr_Sa".split("_");
  export function localeWeekdaysMin(m) {
  	return m === true
  		? shiftWeekdays(this._weekdaysMin, this._week.dow)
  		: m
  		? this._weekdaysMin[m.day()]
  		: this._weekdaysMin;
  }
  
  function handleStrictParse(weekdayName, format, strict) {
  	var i,
  		ii,
  		mom,
  		llc = weekdayName.toLocaleLowerCase();
  	if (!this._weekdaysParse) {
  		this._weekdaysParse = [];
  		this._shortWeekdaysParse = [];
  		this._minWeekdaysParse = [];
  
  		for (i = 0; i < 7; ++i) {
  			mom = createUTC([2000, 1]).day(i);
  			this._minWeekdaysParse[i] = this.weekdaysMin(mom, "").toLocaleLowerCase();
  			this._shortWeekdaysParse[i] = this.weekdaysShort(
  				mom,
  				""
  			).toLocaleLowerCase();
  			this._weekdaysParse[i] = this.weekdays(mom, "").toLocaleLowerCase();
  		}
  	}
  
  	if (strict) {
  		if (format === "dddd") {
  			ii = indexOf.call(this._weekdaysParse, llc);
  			return ii !== -1 ? ii : null;
  		} else if (format === "ddd") {
  			ii = indexOf.call(this._shortWeekdaysParse, llc);
  			return ii !== -1 ? ii : null;
  		} else {
  			ii = indexOf.call(this._minWeekdaysParse, llc);
  			return ii !== -1 ? ii : null;
  		}
  	} else {
  		if (format === "dddd") {
  			ii = indexOf.call(this._weekdaysParse, llc);
  			if (ii !== -1) {
  				return ii;
  			}
  			ii = indexOf.call(this._shortWeekdaysParse, llc);
  			if (ii !== -1) {
  				return ii;
  			}
  			ii = indexOf.call(this._minWeekdaysParse, llc);
  			return ii !== -1 ? ii : null;
  		} else if (format === "ddd") {
  			ii = indexOf.call(this._shortWeekdaysParse, llc);
  			if (ii !== -1) {
  				return ii;
  			}
  			ii = indexOf.call(this._weekdaysParse, llc);
  			if (ii !== -1) {
  				return ii;
  			}
  			ii = indexOf.call(this._minWeekdaysParse, llc);
  			return ii !== -1 ? ii : null;
  		} else {
  			ii = indexOf.call(this._minWeekdaysParse, llc);
  			if (ii !== -1) {
  				return ii;
  			}
  			ii = indexOf.call(this._weekdaysParse, llc);
  			if (ii !== -1) {
  				return ii;
  			}
  			ii = indexOf.call(this._shortWeekdaysParse, llc);
  			return ii !== -1 ? ii : null;
  		}
  	}
  }
  
  export function localeWeekdaysParse(weekdayName, format, strict) {
  	var i, mom, regex;
  
  	if (this._weekdaysParseExact) {
  		return handleStrictParse.call(this, weekdayName, format, strict);
  	}
  
  	if (!this._weekdaysParse) {
  		this._weekdaysParse = [];
  		this._minWeekdaysParse = [];
  		this._shortWeekdaysParse = [];
  		this._fullWeekdaysParse = [];
  	}
  
  	for (i = 0; i < 7; i++) {
  		// make the regex if we don't have it already
  
  		mom = createUTC([2000, 1]).day(i);
  		if (strict && !this._fullWeekdaysParse[i]) {
  			this._fullWeekdaysParse[i] = new RegExp(
  				"^" + this.weekdays(mom, "").replace(".", "\\.?") + "$",
  				"i"
  			);
  			this._shortWeekdaysParse[i] = new RegExp(
  				"^" + this.weekdaysShort(mom, "").replace(".", "\\.?") + "$",
  				"i"
  			);
  			this._minWeekdaysParse[i] = new RegExp(
  				"^" + this.weekdaysMin(mom, "").replace(".", "\\.?") + "$",
  				"i"
  			);
  		}
  		if (!this._weekdaysParse[i]) {
  			regex =
  				"^" +
  				this.weekdays(mom, "") +
  				"|^" +
  				this.weekdaysShort(mom, "") +
  				"|^" +
  				this.weekdaysMin(mom, "");
  			this._weekdaysParse[i] = new RegExp(regex.replace(".", ""), "i");
  		}
  		// test the regex
  		if (
  			strict &&
  			format === "dddd" &&
  			this._fullWeekdaysParse[i].test(weekdayName)
  		) {
  			return i;
  		} else if (
  			strict &&
  			format === "ddd" &&
  			this._shortWeekdaysParse[i].test(weekdayName)
  		) {
  			return i;
  		} else if (
  			strict &&
  			format === "dd" &&
  			this._minWeekdaysParse[i].test(weekdayName)
  		) {
  			return i;
  		} else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
  			return i;
  		}
  	}
  }
  
  // MOMENTS
  
  export function getSetDayOfWeek(input) {
  	if (!this.isValid()) {
  		return input != null ? this : NaN;
  	}
  	var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
  	if (input != null) {
  		input = parseWeekday(input, this.localeData());
  		return this.add(input - day, "d");
  	} else {
  		return day;
  	}
  }
  
  export function getSetLocaleDayOfWeek(input) {
  	if (!this.isValid()) {
  		return input != null ? this : NaN;
  	}
  	var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
  	return input == null ? weekday : this.add(input - weekday, "d");
  }
  
  export function getSetISODayOfWeek(input) {
  	if (!this.isValid()) {
  		return input != null ? this : NaN;
  	}
  
  	// behaves the same as moment#day except
  	// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
  	// as a setter, sunday should belong to the previous week.
  
  	if (input != null) {
  		var weekday = parseIsoWeekday(input, this.localeData());
  		return this.day(this.day() % 7 ? weekday : weekday - 7);
  	} else {
  		return this.day() || 7;
  	}
  }
  
  var defaultWeekdaysRegex = matchWord;
  export function weekdaysRegex(isStrict) {
  	if (this._weekdaysParseExact) {
  		if (!hasOwnProp(this, "_weekdaysRegex")) {
  			computeWeekdaysParse.call(this);
  		}
  		if (isStrict) {
  			return this._weekdaysStrictRegex;
  		} else {
  			return this._weekdaysRegex;
  		}
  	} else {
  		if (!hasOwnProp(this, "_weekdaysRegex")) {
  			this._weekdaysRegex = defaultWeekdaysRegex;
  		}
  		return this._weekdaysStrictRegex && isStrict
  			? this._weekdaysStrictRegex
  			: this._weekdaysRegex;
  	}
  }
  
  var defaultWeekdaysShortRegex = matchWord;
  export function weekdaysShortRegex(isStrict) {
  	if (this._weekdaysParseExact) {
  		if (!hasOwnProp(this, "_weekdaysRegex")) {
  			computeWeekdaysParse.call(this);
  		}
  		if (isStrict) {
  			return this._weekdaysShortStrictRegex;
  		} else {
  			return this._weekdaysShortRegex;
  		}
  	} else {
  		if (!hasOwnProp(this, "_weekdaysShortRegex")) {
  			this._weekdaysShortRegex = defaultWeekdaysShortRegex;
  		}
  		return this._weekdaysShortStrictRegex && isStrict
  			? this._weekdaysShortStrictRegex
  			: this._weekdaysShortRegex;
  	}
  }
  
  var defaultWeekdaysMinRegex = matchWord;
  export function weekdaysMinRegex(isStrict) {
  	if (this._weekdaysParseExact) {
  		if (!hasOwnProp(this, "_weekdaysRegex")) {
  			computeWeekdaysParse.call(this);
  		}
  		if (isStrict) {
  			return this._weekdaysMinStrictRegex;
  		} else {
  			return this._weekdaysMinRegex;
  		}
  	} else {
  		if (!hasOwnProp(this, "_weekdaysMinRegex")) {
  			this._weekdaysMinRegex = defaultWeekdaysMinRegex;
  		}
  		return this._weekdaysMinStrictRegex && isStrict
  			? this._weekdaysMinStrictRegex
  			: this._weekdaysMinRegex;
  	}
  }
  
  function computeWeekdaysParse() {
  	function cmpLenRev(a, b) {
  		return b.length - a.length;
  	}
  
  	var minPieces = [],
  		shortPieces = [],
  		longPieces = [],
  		mixedPieces = [],
  		i,
  		mom,
  		minp,
  		shortp,
  		longp;
  	for (i = 0; i < 7; i++) {
  		// make the regex if we don't have it already
  		mom = createUTC([2000, 1]).day(i);
  		minp = this.weekdaysMin(mom, "");
  		shortp = this.weekdaysShort(mom, "");
  		longp = this.weekdays(mom, "");
  		minPieces.push(minp);
  		shortPieces.push(shortp);
  		longPieces.push(longp);
  		mixedPieces.push(minp);
  		mixedPieces.push(shortp);
  		mixedPieces.push(longp);
  	}
  	// Sorting makes sure if one weekday (or abbr) is a prefix of another it
  	// will match the longer piece.
  	minPieces.sort(cmpLenRev);
  	shortPieces.sort(cmpLenRev);
  	longPieces.sort(cmpLenRev);
  	mixedPieces.sort(cmpLenRev);
  	for (i = 0; i < 7; i++) {
  		shortPieces[i] = regexEscape(shortPieces[i]);
  		longPieces[i] = regexEscape(longPieces[i]);
  		mixedPieces[i] = regexEscape(mixedPieces[i]);
  	}
  
  	this._weekdaysRegex = new RegExp("^(" + mixedPieces.join("|") + ")", "i");
  	this._weekdaysShortRegex = this._weekdaysRegex;
  	this._weekdaysMinRegex = this._weekdaysRegex;
  
  	this._weekdaysStrictRegex = new RegExp(
  		"^(" + longPieces.join("|") + ")",
  		"i"
  	);
  	this._weekdaysShortStrictRegex = new RegExp(
  		"^(" + shortPieces.join("|") + ")",
  		"i"
  	);
  	this._weekdaysMinStrictRegex = new RegExp(
  		"^(" + minPieces.join("|") + ")",
  		"i"
  	);
  }
  